承诺数组和 Promise.all()

array of promises and Promise.all()

我有这样的 Promise 数组:

let promisesArray = [
    service1.load('blabla'),
    service2.load(), // throws an errors
];

我想全部执行它们并像这样捕获它们的错误

Promise.all(promisesArray)
    .then(() => doStuffs())
    .catch((err) => handleError(err));

工作正常,但我现在想在另一个承诺的 then() 中执行此操作:

baseService()
    .then(() => Promise.all([
        service1.load('blabla'),
        service2.load(), // throw an errors
    ]))
    .catch((err) => handleError(err));

只要我直接在 Promise.all() 中写入数组,这个也可以,但是如果我想使用 promiseArray,请提前定义,如:

baseService()
    .then(() => Promise.all(promisesArray))
    .catch((err) => handleError(err));

然后,catch() 是预期的 运行,但我在控制台中出现错误

publish.js:45784 EXCEPTION: Error: Uncaught (in promise): ...

但我想使用最后一个解决方案,因为我的数组是根据某些条件通过将 Promises 推送给它而生成的。 (第一个例子工作得很好,我不知道有什么不同)

将 catch 添加到我的每个 promise 中,同时将它们添加到数组中可以解决我的问题,但我想找到更好的解决方案。

非常感谢您对此提供的帮助。

PS:我正在使用 angular2 和 zone.js 如果它改变了某些东西

既然你用的是angular2,为什么不用Observable和Http

var load1 = http.get('url1'),
    load2 = http.get('url2'),
    load3 = http.get('url3');

Observable.forkJoin(load1, load2, load2, function(res1, res2, res3){
    // manipulate your results here and return the reduced result

    return { whatever : { res1: res1, res2: res2, res3: res3 } }

}).
subscribe(function(finalResult){
     console.log(finalResult); // { whatever : { res1: res1, res2: res2, res3: res3 } }
});

我找到了让它工作的方法。

我创建了一个函数数组,而不是一个 promise 数组,return 一个 Promise:

let promisesArray = [
    () => service1.load('blabla'),
    () => service2.load(), // throws an errors
];
promisesArray.push(() => service2.load())

然后我使用 Array.prototype.map() 来 运行 Promise.all() 中的承诺:

baseService()
    .then(() => Promise.all(promisesArray.map(promise => promise())))
    .catch((err) => handleError(err));

这正在解决我的问题,但不确定这是否是最好的方法。 如果有人有更好的主意,我会采纳。

一旦您执行一个异步函数(return是一个承诺),它就会开始运行在后台(kindof)执行该承诺可能随时解决或拒绝的任务当你 运行

let promisesArray = [
    service1.load('blabla'),
    service2.load(), // throws an errors
];

这些服务正在关闭并加载数据,如果它们 return 在附加 .then() 之前,它们将保留它们的值,并且只要您调用 promisesArray[0].then(x => console.log(x)) then 函数将 运行 具有该值

但是如果这些服务之一抛出错误并且还没有附加 .catch 函数,它们将保留错误以便将其发送到稍后指定的 .catch() 函数,但它们也会抛出控制台错误 - 因为他们不知道是否会附加 catch 函数,如果 promise 只是默默地失败并且错误消失,那将是令人沮丧的。

如果您真的希望您的 promisesArray 在 baseService() 之后执行,那么您的想法是让 promisesArray 成为一个启动异步任务和 return 承诺的函数数组 - 这是一个很好的想法。 然而,传递一个 return 是一个承诺数组的函数可能更好,而不是传递一个 return 承诺的函数数组(如上所述)

const getPromises = () => [
    service1.load('blabla'),
    service2.load(), // throws an errors
]

然后使用

执行
baseService()
    .then(() => Promise.all(getPromises()))
    .catch((err) => handleError(err));

这只会在 baseServce() 完成后启动您的 service1.load,所有错误一旦发生就会被捕获