承诺构造函数是否需要解析函数?

Is the resolve function necessary for promise constructor?

考虑以下承诺数组

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);

是否需要解析函数?

我们可以省略它并把 promise 变成这样吗?

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

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

我认为你对 async/await 和承诺感到困惑。

当您指定异步函数时,它将始终 return 解析承诺,除非您在函数内部抛出一个未被捕获的错误。

例如:

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

您可以使用 promises 实现相同的示例

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

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

但是,在你的情况下,你 :

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

Can we omit it and turn the promise into something like this?

不,你不能。如果不调用 resolve(),您的 new Promise() 将永远无法解析。当您随后致电:

const a = Promise.all(promiseArray);

None promiseArray 中的承诺将永远兑现。因此,承诺 a 永远不会解决。所以,none 这将是有用的,你将无法知道什么时候一切都完成了执行。

看来您真的不需要在此处将任何内容包装在 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);
});