Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous javascript中的一种函数,它返回承诺并重试内部异步过程最佳实践_Asynchronous_Promise_Es6 Promise - Fatal编程技术网

Asynchronous javascript中的一种函数,它返回承诺并重试内部异步过程最佳实践

Asynchronous javascript中的一种函数,它返回承诺并重试内部异步过程最佳实践,asynchronous,promise,es6-promise,Asynchronous,Promise,Es6 Promise,我有一个函数,它返回一个javascript承诺,并在其中运行一些异步代码。异步代码需要重试几次,以防失败。 我一直在这样做,直到我观察到一些奇怪的行为,这让我怀疑我是否做对了。所以我不得不改变它。两条路线都在下面。 我知道为什么第一种方法(asyncFunc)不起作用,如果有人能分享一些关于它的技术清晰性,我将不胜感激。 对于第二种方法(ayncFunc_更新版),有没有关于如何做得更好的建议 var\u retryCount=0; //这就是我在做的 函数asyncFunc(){ 返回新承

我有一个函数,它返回一个javascript承诺,并在其中运行一些异步代码。异步代码需要重试几次,以防失败。 我一直在这样做,直到我观察到一些奇怪的行为,这让我怀疑我是否做对了。所以我不得不改变它。两条路线都在下面。 我知道为什么第一种方法(asyncFunc)不起作用,如果有人能分享一些关于它的技术清晰性,我将不胜感激。 对于第二种方法(ayncFunc_更新版),有没有关于如何做得更好的建议

var\u retryCount=0;
//这就是我在做的
函数asyncFunc(){
返回新承诺(功能(履行、拒绝){
doAsync()
.然后(完成)
.catch(重试);
函数重试(PromiserResult){
如果(_retryCount<3){
_retryCount++;
返回asyncFunc();
}
否则{
拒绝(承诺人结果);
}
}
});
}
//这就是我现在正在做的
函数ayncFunc_(){
返回新承诺(功能(履行、拒绝){
var-retryCount=0;
doAsync()
.然后(完成)
.捕获(拒绝);
函数onReject(bmAuthError){
如果(retryCount<3){
retryCount++;
日志警告(错误);
doAsync()
.然后(完成)
.捕获(拒绝);
}
否则{
完成(假);
}
}
});                 

};最佳实践是避免错误。基本上,
newpromise
的存在主要是为了包装非承诺API,所以如果您的函数已经返回了承诺,那么通常有一种方法可以避免使用它

如果您正在进行较低的固定次数重试,那么您的案例非常简单:

function ayncFunc() {
  return doAsync().catch(doAsync).catch(doAsync).catch(doAsync);
};
对于可配置的重试次数,您可以将其扩展为:

var retries = 3;

function ayncFunc() {
  var p = doAsync();
  for (var i = 0; i < retries; i++) {
    p = p.catch(doAsync);
  }
  return p;
};
var重试次数=3次;
函数ayncFunc(){
var p=doAsync();
对于(变量i=0;i
或者,对于较高的重试次数,可以使用递归方法:

function ayncFunc() {
  function recurse(i) {
    return doAsync().catch(function(e) {
      if (i < retries) {
        return recurse(++i);
      }
      throw e;
    });
  }
  return recurse(0);
};
函数ayncFunc(){
函数递归(i){
返回doAsync().catch(函数(e){
如果(i<重试次数){
返回递归(++i);
}
投掷e;
});
}
返回递归(0);
};
var控制台={log:msg=>div.innerHTML+=msg+”
“}; 函数doAsync(){ console.log(“doAsync”); 退货承诺。拒绝(“否”); } 函数ayncFunc(){ 返回doAsync().catch(doAsync).catch(doAsync).catch(doAsync); }; var重试次数=3次; 函数ayncFunc2(){ var p=doAsync(); 对于(变量i=0;i
你在哪里增加\u retryCount?忘了。更新了代码我建议使用递归方法,而不是构造很长的链。@Bergi我怀疑开销很大,因为在常规(成功的)代码流中跳过了捕获处理程序,但为了完整性,我添加了一个递归示例。谢谢您的想法。@jib在递归方法中,首先返回一个承诺,在异常情况下,将另一个承诺返回给被调用的对象。这难道不会让ayncFunc调用者感到困惑吗?@ab在
asyncFunc
调用者只看到一个承诺,一个立即从
doAsync().catch()
返回的承诺,但是这个承诺很快就变成了另一个未决承诺(或者“锁定到”可能是更好的表达方式,因为对它调用了
拒绝
),第二次调用
recurse()
返回的一个。第一个承诺仍然悬而未决,并且在第二个承诺达成并继承其价值之前不会达成(被履行或拒绝)。这是使用中的术语。@jib谢谢,我现在理解这个场景了。现在我对doAsync在第一次尝试时实现的理想场景感到困惑。asyncFunc调用方有doAsync().catch()承诺,在这种情况下如何实现这一承诺?