【问题标题】:Is the resolve function necessary for promise constructor?Promise 构造函数是否需要 resolve 函数?
【发布时间】:2020-07-26 14:26:49
【问题描述】:

考虑以下承诺数组

const promiseArray = [1, 2, 3].map(num =>
  new Promise(async resolve => {
    while (num > 0) {
      await foo();
      num--;
    }
    await bar(num);
    resolve(); // No value to return
  })
);
const a = Promise.all(promiseArray);

resolve函数有必要吗?

我们可以省略它并将承诺变成这样吗?

const promiseArray = [1, 2, 3].map(num =>
  new Promise(async () => {
    while (num > 0) {
      await foo();
      num--;
    }
    await bar(num);
  })
);
const a = Promise.all(promiseArray);

【问题讨论】:

  • Never pass an async function as the executor to new Promise!所以简化为const aPromise = foo(1,2,3);const aPromise = Promise.resolve(foo(1, 2, 3));
  • resolve 函数有必要吗? - 如果没有 resolve 函数调用,aPromise 将永远无法实现。要实现它,你必须调用resolve函数
  • 嗯,你试过了吗?等待aPromise。您的第二个 sn-p 将不起作用。
  • 如果 foo 返回一个承诺,如果你正在等待它,它必须返回,你为什么要把它包装在另一个承诺中?
  • 感谢您的更新,但这里的“从不”实际上意味着从不。而你的第二个 sn-p 在你尝试时仍然不起作用。

标签: javascript ecmascript-6 promise es6-promise


【解决方案1】:

是的,使用 new Promise 构造函数时需要调用 resolvereject,否则 promise 将保持未决状态。

但是,在你的情况下,你 shouldn't be using new Promise at all:

const promiseArray = [1, 2, 3].map(async num => {
  while (num > 0) {
    await foo();
    num--;
  }
  await bar(num);
});
const a = Promise.all(promiseArray);

【讨论】:

  • 我试过了,但如果没有 Promise 构造函数,它就无法工作。你能帮忙检查我的代码吗?我已经更新了答案。
  • @Max 这不是我回答的代码。如果您正在做其他事情,请ask a new question 使用您的实际 代码。关于问题更新中的代码,如果您只想做array.flat().forEach(console.log),则根本不应该使用承诺 - 没有什么异步的!
【解决方案2】:

我们可以省略它并将承诺变成这样吗?

不,你不能。如果不致电resolve(),您的new Promise() 将永远无法解决。当你打电话时:

const a = Promise.all(promiseArray);

promiseArray 中的任何承诺都不会解决。所以,a 的承诺永远不会解决。因此,这些都没有任何用处,您将无法知道一切何时执行完毕。

看起来你真的不需要在这里把任何东西包装在一个 Promise 中。你可以这样做:

async function runLoop() {
    for (let i = 1; i <= 3; i++) {
        let num = i;
        while (num > 0) {
          await foo();
          num--;
        }
        await bar(num);    // note this will always be bar(0)
    }
}

runLoop().then(() => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});

或者,如果您希望单独的循环并行运行,您可以这样做:

const promiseArray = [1, 2, 3].map(async num => {
  while (num > 0) {
    await foo();
    num--;
  }
  await bar(num);    // note this will always be bar(0)
});
Promise.all(promiseArray).then(() => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});

【讨论】:

    【解决方案3】:

    当你使用构造函数创建promise时,应该调用第一个参数来解析promise,调用函数的第二个参数(如果存在)来拒绝promise。如果您没有调用任何参数,那么 Promise 将始终处于挂起状态。 More information

    我认为您对 async/await 和 Promise 感到困惑。

    当您指定异步函数时,它将始终返回已解决的承诺,除非您在未捕获的函数内部抛出错误。

    例如:

    async function hello(){ return 1}
    hello().then((val) => console.log(val));
    

    同样的例子,你可以使用 Promise 实现

    let promise = return new Promise((resolve) => return resolve(1));
    promise.then((val) => console.log(val));
    

    【讨论】:

    • 其实我的情况涉及的不止一个Promise。请再次检查问题。我已经更新了它。谢谢:)
    • 同样的逻辑也适用于 promise.all。您必须解决才能从 promise.all 获得结果,如果您不解决您的 promise.all 将永远不会解决或拒绝它将始终处于待处理状态。
    猜你喜欢
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 2013-10-25
    • 2021-05-25
    • 2017-07-15
    相关资源
    最近更新 更多