【问题标题】:ES6 Promises.all() does not execute all (no error caught in promises)ES6 Promises.all() 不会全部执行(promises 中没有发现错误)
【发布时间】:2019-11-03 00:18:12
【问题描述】:

我正在尝试创建一个 Promises 数组,它会在完成时向控制台打印一条消息。但是,即使数组中有 10 个 promise 对象,它似乎也只打印一次。

我已经尝试过ES6 Promises/calling a function after multiple promises are fulfilled (can't use Promises.all)中的解决方案 但它仍然不起作用。

function fillArrayWithPromise(promise, numTimes) {
  let promiseArr = Array(numTimes).fill(promise);
  console.log(promiseArr.join("-"));
  return promiseArr
}

var sendStuffB = new Promise(
  function(resolve, reject) {
    try {
      console.log("submitted one req");
    } catch (error) {
      console.log("Error: " + error);
    }
  }
)

let testA = fillArrayWithPromise(sendStuffB, 10);

Promise.all(
  testA.map(promise => Promise.resolve(promise).catch(err => console.log(error)))
).then(function() {
  console.log("End");
});

我希望控制台打印 10 次“发送一个对象”,但它只打印到控制台一次,之后会无限期地继续运行。

这是错误日志: 运行测试脚本... 发送了一个对象 提交了一份申请 [object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]

【问题讨论】:

  • "但它只打印到控制台一次" - 因为你的脚本中只有一个实际的Promise。 promise 中的 fillArrayWithPromise 是对 sendStuffB 的引用,因此您以该引用的 numTimes 副本数组结尾 - 但没有引用的 Promise 的副本
  • 注意:在数组中复制相同的 Promise 对象是非常没用的。
  • 这里有两个错误:你没有解决承诺,并且你有相同的承诺(只会执行一次)10次。

标签: javascript node.js es6-promise


【解决方案1】:

你没有在 promise 中调用 resolve 函数,所以它们永远不会完成。尝试这样做:

var sendStuffB = new Promise(
  function(resolve, reject) {
    try {
      console.log("submitted one req");
      resolve();
    } catch (error) {
      console.log("Error: " + error);
      reject(error);
    }
  }
)

【讨论】:

  • @Andreas - 创建 promise 时调用函数的时间。请注意,函数永远不会完成,而不是永远不会被调用
  • @Tom 无法解析会阻止打印End。它不应该影响submitted one req
  • @AyushGupta 你是对的,只有一个承诺被等待 10 次(而不是像在你的答案中创建 10 个单独的承诺,这可能是想要的)
  • @Andreas Promise.resolve 创建一个新的 Promise,它会立即解析为您传入的值,但是当该值是 Promise 时,它​​会等待该 Promise 解析并返回其解析值。这不会强制传入的 Promise 解决,而是等待它。
【解决方案2】:

因为sendStuffB只是一个promise,所以只解析一次。数组中的所有其他项目都引用同一个已解决的承诺。

取而代之的是,在fillArrayWithPromise 函数中,传递一个返回承诺的函数,并为每个数组项单独调用该函数。

另外,请务必根据需要在 promise 构造函数中解析或拒绝 promise。

function fillArrayWithPromise(promiseFn, numTimes) {
  let promiseArr = Array(numTimes).fill(promiseFn).map(fn => fn()); //see this
  return promiseArr
}

var sendStuffB = () => new Promise(  // converted to function
  function(resolve, reject) {
    try {
      console.log("submitted one req");
      resolve(); // remember to resolve
    } catch (error) {
      console.log("Error: " + error);
      reject(error); // reject
    }
  }
)

let testA = fillArrayWithPromise(sendStuffB, 10);

Promise.all(
  testA.map(promise => Promise.resolve(promise).catch(err => console.log(error)))
).then(function() {
  console.log("End");
});

【讨论】:

  • @Andreas 不,不是,Promise.resolve(promise) 在这种情况下会解析为未解决的承诺。
  • 可以看到Promise.resolve(new Promise(() => {})).then(console.log)
【解决方案3】:

这是 Promise.all 功能的一个基本示例。

也许对你有帮助。

const delayArray = [1000,1500,2000];

const promises = delayArray.map((item) => {
  return new Promise((resolve,reject) => {
    setTimeout(()=>{
      console.log('I was resolved in' + item + 'ms');
      resolve('Resolved' + item + 'ms');
    },item);
  });
});

Promise.all(promises)
.then((values) => console.log(values));

【讨论】:

    猜你喜欢
    • 2021-06-07
    • 2018-03-15
    • 1970-01-01
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 2018-12-21
    • 1970-01-01
    相关资源
    最近更新 更多