Javascript 如何在ES6中重试承诺
我一直在试图找出如何最好地实现重试,例如,使用承诺进行失败的下载。我最好的猜测是用一个新的promise来解析一个promise(见下面的伪代码),但我在文档中只能找到这个promise.resolve()可以用一个thenable来调用(我相信,也可以用promise来调用)。这是否也适用于promise构造函数中的resolve回调?我的方法是正确的还是有更好的方法实现重试Javascript 如何在ES6中重试承诺,javascript,node.js,ecmascript-6,promise,es6-promise,Javascript,Node.js,Ecmascript 6,Promise,Es6 Promise,我一直在试图找出如何最好地实现重试,例如,使用承诺进行失败的下载。我最好的猜测是用一个新的promise来解析一个promise(见下面的伪代码),但我在文档中只能找到这个promise.resolve()可以用一个thenable来调用(我相信,也可以用promise来调用)。这是否也适用于promise构造函数中的resolve回调?我的方法是正确的还是有更好的方法实现重试 function getdata(url) { return new Promise(function(reso
function getdata(url) {
return new Promise(function(resolve, reject) {
ajaxcall({
url: url,
success: function(data) { resolve(data); },
failure: function(err) {
if(retriable(err)) {
resolve(getdata(url));
}
else {
reject(err);
}
}
});
});
}
你的方法会奏效的。将承诺传递给承诺构造函数的resolve回调时,该承诺的resolution值将用作“外部”承诺的resolution值 将
ajaxcall
封装在承诺返回函数中可能会更干净,这样就不会混合和匹配承诺和回调范例
function fetch(url) {
return new Promise(function(resolve, reject) {
ajaxcall({
url: url,
success: resolve,
failure: reject
});
});
}
function getdata(url) {
return fetch(url)
.catch(function(err) {
if(retriable(err)) {
return getdata(url); // or fetch(url) to retry only once
} else {
throw err;
}
});
}
您可以更改代码以调用Promise内部的内部函数。大概是这样的:
function getdata(url) {
return new Promise(function(resolve, reject) {
function call() {
return ajaxcall({
url: url,
success: function(data) { resolve(data); },
failure: function(err) {
if(retriable(err)) {
call();
}
else {
reject(err);
}
}
});
}
call();
});
}
这很容易找到:
newpromise(resolve=>resolve(Promise.resolve(42)),然后(v=>console.log(v))代码>日志42
,不是承诺。因此,是的,它似乎也适用于resolve
代码>承诺重试的一般有限次数var retryP=(fn,retry)=>fn().catch(err=>retry>0?retryP(fn,retry-1):承诺.拒绝(err))代码>请参阅:注意,根据现代规则,这可能会被标记为错误代码,因为内部fetch
没有错误处理,JS引擎被鼓励不允许让错误消失在空白中的承诺。您可以再次返回getdata(url)
,而不是fetch(url)
@Mike'Pomax'Kamermans请详细说明或指向提到此规则的资源?谁来做“标记”?一根短绒?发动机本身。例如,Node.js当前使用的V8版本在告诉他们运行newpromise(函数(resolve,reject){throw new Error('test');})
时将发出警告unhandledPromisejectionWarning:Unhandled promisejection(拒绝id:2):Error:test
。在这种特殊情况下:通过调用fetch
而不是getdata
,我们失去了“查看”(并处理)与初始故障无关的错误的能力(例如,硬件故障导致第二次尝试时出现网络错误),但在上述情况下,getdata()
的调用者是否有责任添加.catch()
处理程序?如果getdata()
的调用者没有捕捉到最终的错误,您的建议将如何缓解问题?当然,但是getdata已经有了处理重试的代码,利用这些代码并确保retreable(err)
在需要重试的次数内做正确的事情远比一次重试更有价值“重试一次,且仅重试一次”构造。您的建议不错,但只需一个几乎微不足道的更改就可以让它变得更好。