【问题标题】:Will resolve in promise loop break loop iteration?将在承诺循环中断循环迭代中解决吗?
【发布时间】:2020-02-07 20:49:23
【问题描述】:

我在这样的循环中调用异步函数(类似于上传文件列表):

return new Promise(async function(resolve, reject) { 
  for (let i = 0; i < list.length; i++) {
    let response = await myAsyncFunction();
    if (response.ok === false) {
      resolve({error: "Something goes wrong"});
      // break; - is this required?
    }
  }
}
async function myAsyncFunction() {
  return new Promise(async function(resolve, reject) {
     resolve code....
  }
}

如果在我调用resolve() 的循环中,我调用resolve() 将循环继续迭代,否则它将停在那里。
如果我在此之前解决,基本上我需要在循环中调用break;吗?

【问题讨论】:

标签: javascript promise es6-promise


【解决方案1】:

会在promise loop break loop 迭代中解决吗?

不,不会。如果你想打破循环,你必须使用breakreturn

但作为一个单独的东西,还有其他几个问题:

  1. 在该代码中没有理由使用new Promiseasync 函数返回承诺,无需包装。

  2. 使用带有分辨率的错误标志通常不是最佳实践。使用 rejection 表示失败,而不是 fulfillment 并带有错误代码。

所以:

return (async function(resolve, reject) { 
  for (let i = 0; i < list.length; i++) {
    let response = await myAsyncFunction();
    if (response.ok === false) { // I'd use `if (!response.ok) {`
      throw new Error("something goes wrong");
    }
  }
  // Presumably return something here
})();

(看起来有点尴尬。如果您提供更多上下文,可能会使其看起来不那么尴尬。)

同样,myAsyncFunction 要么 A) 不应该是 async 函数,要么 B) 不应该使用 new Promise。见What is the explicit promise construction antipattern and how do I avoid it?

最后,这是可疑的:

let response = await myAsyncFunction();
if (response.ok === false) { // I'd use `if (!response.ok) {`
  throw new Error("something goes wrong");
}

除非有一个非常充分的理由,否则myAsyncFunction 在出现问题时应该拒绝而不是履行其承诺。 (数十万个使用fetch 而不检查response.ok 的错误代码示例证明了这一点。)

【讨论】:

【解决方案2】:

Resolve 将打破循环甚至嵌套循环,正如我从这段代码中看到的那样:

function loops() {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < 10; i++) {
      for (let j = 0; j < 10; j++) {
        if (j === 1) {
          resolve("first");
        }

        if (j === 5) {
          resolve("second");
        }
      }
    }
    resolve("third");
  });
}

async function execute() {
  let test = await loops();
  console.log(test);
}

execute();

【讨论】:

【解决方案3】:

不要同时使用 Promise 构造函数和async functions。那只会引起像这样的头痛。只需使用 async 函数,那么很明显您实际上可以只使用return

 return (async function() { // IIFE is all you need, will result in a Promise itself
   for (let i = 0; i < list.length; i++) {
     let response = await myAsyncFunction();
     if (response.ok === false) {
       return {error: "Something goes wrong"};
     }
   }
})();

Read on

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 2017-02-21
    相关资源
    最近更新 更多