- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
目标
我正在尝试创建一系列 promise “增强器”,这些 promise 将围绕简单的 http 请求等现有 promise 添加功能(例如缓存、排队、重定向处理等)。
问题
我在使用这种增强 promise 的方法时遇到的问题是,如果增强功能向 promise 添加了任何函数或可公开访问的属性(或者如果我正在包装一个已经增强的 promise,例如 restangular 请求),这些是当我通过返回一个新的 $q
将它包装在一个新的 promise 中时丢失了。
问题
我可以使用什么模式来增强或包装 promise(如下面两个示例所示),同时又不会丢失 promises 可能具有的任何其他(非冲突)增强功能?
示例 1
这是一个自动处理 503-Retry-After 错误的例子:
function _enhancePromiseWithAutoRetry(promise) {
var enhancedPromise = $q(function(resolve, reject) {
var newReject = get503Handler(this, resolve, reject);
promise.then(resolve, newReject);
});
// 503 handling isn't enabled until the user calls this function.
enhancedPromise.withAutoRetry = function(onRetry, timeout) {
var newPromise = angular.copy(this);
newPromise._503handled = true;
newPromise._503onRetry = onRetry;
newPromise._503timeout = timeout;
return newPromise;
};
return enhancedPromise;
}
我的想法是,如果我返回一个使用上述功能增强的 promise ,用户可以:
someRequest.withAutoRetry().then(onSuccess, onError);
或者更清楚(使用链接):
someRequest.then(onSuccess, onAnyError)
.withAutoRetry().then(onSuccess, onNon503Error);
这里,如果服务器繁忙,第一次调用 then(...)
可能会立即出错,但 .withAutoRetry()
之后的调用将轮询服务器重复请求直到响应成功,否则返回非RetryAfter
错误。
示例 2
这是另一个添加自定义缓存行为的示例:
function _enhancePromiseWithCache(promise, cacheGet, cachePut) {
// Wrap the old promise with a new one that will get called first.
return $q(function(resolve, reject) {
// Check if the value is cached using the provided function
var cachedResponse = cacheGet !== undefined ? cacheGet() : undefined;
if(cachedResponse !== undefined){
resolve(cachedResponse);
} else {
// Evaluate the wrapped promise, cache the result, then return it.
promise.then(cachePut);
promise.then(resolve, reject);
}
});
}
这允许库设置一个数据缓存,可以用来代替向服务器发出请求,并且可以在请求完成后添加。例如:
lib.getNameOrigin = function(args) {
var restRequest = Restangular.all('people').one(args.id).get('nameOrigin');
// Cache, since all people with the same name will have the same name origin
var enhancedPromise = _enhancePromiseWithCache(restRequest,
function(){ return nameOrigins[args.name]; },
function(val){ nameOrigins[args.name] = val; });
return enhancedPromise;
}
别处
// Will transparently populate the cache
lib.getNameOrigin({id: 123, name:'john'}).then(onSuccess, onError).then(...);
还有其他地方
// Will transparently retrieve the result from the cache rather than make request
lib.getNameOrigin({id: 928, name:'john'}).then(onSuccess, onError);
可能的解决方案
我考虑过复制原始 promise ,但随后使用引用原始 promise 的 then
的实现覆盖新的 then
函数(使用 Proxy Pattern ) ,但这安全吗?我知道 promise 不仅仅是 then
函数。
最佳答案
解决方案不是增强 promise 本身,而是增强创建它们的工厂。
使用函数式编程和/或面向方面的编程方法来修饰原始函数。这不仅不容易出错,而且更加简洁、可组合和可重用。
function decorate(makeThenable) {
return function(...args) {
… // before creating the thenable
return makeThenable(...args).then(function(value) {
… // handle fulfillment
return …; // the resulting value
}, function(error) {
… // handle rejection
return …; // (or throw)
});
};
}
var decorated = decorate(myThenablemaker);
decorated(…).then(whenFulfilled, whenRejected);
示例 1:
function withAutoRetry(request, timeout) {
return function() {
var args = arguments;
return request.apply(null, args).catch(function handle(e) {
if (e instanceof Http503Error) // or whatever
return request.apply(null, args).catch(handle);
else
throw e;
});
};
}
withAutoRetry(someRequest)().then(onSuccess, onError);
withAutoRetry(function() {
return someRequest().then(onSuccess, onAnyError);
})().then(onSuccess, onNon503Error);
示例 2:
function withCache(request, hash) {
var cache = {};
if (!hash) hash = String;
return function() {
var key = hash.apply(this, arguments);
if (key in cache)
return cache[key];
else
return cache[key] = request.apply(this, arguments);
};
}
lib.getNameOrigin = withCache(function(args) {
return Restangular.all('people').one(args.id).get('nameOrigin');
}, function(args) {
return args.name;
});
关于javascript - Angular : Enhancing or wrapping promises with pre/post resolve/reject actions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25429386/
内的和
看似不可能完成的任务。我有一个服务器输出,其中包含 内的转储。不幸的是,我碰巧转储了一个包含一些 html 标签的文件。我需要转换任何内部 HTML 实体,以便当我将数据附加到 DOM 时结构不会
标签之间的所有内容
我正在读取 .html 文件: const htmlin = String(fs.readFileSync(inputHtml) || ''); const splitted = htmlin.spl
我在 中输入了一些文本, 我输入了一些换行符、空格等。故意。但是,在提交文本并在 内呈现之后, 换行符,空格消失了,它们被类似 \r\n\r\n 的东西所取代, 怎么了?如何保持原始格式? 我
我在里面有很多内容我正在打印的标签。我正在对打印样式使用媒体查询。一切都很好,只是第一页的最后一行被剪切了。其中一半保留在第一页,另一半显示在下一页。我不知道如何将溢出转移到下一页。 最佳答案 我想通
并用括起来是否安全?
一些用户生成的文本(可能包含脚本/代码)将向公众展示。如果我过滤掉所有 和标记并用 将结果文本括起来和 ,用户提交的脚本有机会被执行吗? 请给我一个如何破解这个保护方案的例子。 最佳答案 Is it
标签中移除
我制作了简单的 BBCode 脚本,它运行良好。但后来我使用 javascript 库来美化我在 中的代码. 现在我面临的唯一问题是 中每行代码后的标签标签。 所以问题是我怎样才能删除 在
`中删除 ``?
Markdown 中的三个反引号渲染为 ... 。更具体地说, # in markdown ```java ``` # render as ... # my expecting result
标签内的方括号 (<>) 替换除标签内的换行符
我使用 question 中提供的答案替换了 pre 标签外的所有换行符. \n(?![^) 它工作正常,直到 pre 标签中的内容有 括号。 例如,输入: Test contennt for re
标签中获取选定的文本和文本索引,其中偏移量是 pre 的开始
所以我有一个像这样的前置标签: Some content, more content. Coloured content. Some more content 我想做的是使用绑定(bind) mou
我正在开发一个 android 项目,我们在其中使用 ant 构建我们的版本。在更改代码中的 versionName 和其他一些标志时,我们使用 Android-ant 目标 -pre-compile
"); ..... 回显 (""); ?> 是什么意思?
问题是标签 我看过我正在编写的一个脚本,并使用了它: echo (""); ........ echo (""); 它到底做了什么? 它是 Html 标签还是 PHP? 我在 Google 上进行了
我想知道哪些语言和工具(调试器、IDE、分析器、库等)可供想要为 Palm Pre 开发的人使用。 另外,我想知道存在哪些必须注意的技术限制。 最佳答案 有一个 JavaScript 函数库,用于与基
我目前有一个简单的 pre-commit 钩子(Hook)用于我的项目(在 R 中,虽然这是这个问题的附带),它运行单元测试: #!/bin/sh a=$(Rscript tests/testthat
我目前有一个简单的 pre-commit 钩子(Hook)用于我的项目(在 R 中,虽然这是这个问题的附带),它运行单元测试: #!/bin/sh a=$(Rscript tests/testthat
标签中的文本的空白缩进,不包括文档中标签的当前缩进级别?
我试图在网站上显示我的代码,但在正确保留空格缩进时遇到问题。 例如给定以下片段: Here is my code: def some_funtion ret
"的快捷方式 ;print_r($myarray);echo "";
是否有快捷方式 echo ""; print_r($myarray); echo ""; 为了获得数组的可读格式而键入这些内容真的很烦人。 最佳答案 这是最短的: echo '',print_r
我有一个简单的 python 项目,目前只有一个文件。它存在于我的项目的 static/cgi-bin 文件夹中。目前,在我的目录的底部,我有一个 .pre-commit-config.yaml 文件
Moses Tokenizer是广泛应用于机器翻译和自然语言处理实验的分词器。 有一行正则表达式检查: if (($pre =~ /\./ && $pre =~ /\p{IsAlpha}/) ||
在我的一个 PHP 网站上,我需要为我的用户提供选择某些行以从网站上的所有搜索结果(查询)中排除的功能。 我应该采取哪种方式来处理排除,我应该: 1) 每当用户登录(或通过查询更新它)时,预编译排除行
考虑以下代码段。 <p class="text-centre"> </bHello World></b> </p> 然后我有另一个div如下 正如您在第一个 div 中
我是一名优秀的程序员,十分优秀!