0

我有这样的承诺数组:

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 添加到我的每个承诺中,同时将它们添加到数组中可以解决我的问题,但我想找到一个更好的解决方案。

我真的很感激一些帮助。

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

4

3 回答 3

2

一旦你执行了一个异步函数(一个返回承诺的函数),它就会开始在后台运行任务(kindof),承诺可能会在你运行的那一刻起随时解决或拒绝

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

这些服务正在关闭并加载数据,如果它们在附加 .then() 之前返回,它们将保持它们的值,并且一旦你调用 promisesArray[0].then(x => console.log(x)) then 函数将使用该值运行

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

如果您真的希望您的 promisesArray 在 baseService() 之后执行,那么您将 promisesArray 设为启动异步任务并返回 promise 的函数数组的想法是一个好主意。然而,传入一个返回承诺数组的函数可能会更好,而不是传入一个返回承诺的函数数组(如上所述)

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

然后执行使用

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

这只会在 baseServce() 完成后启动你的 service1.load,所有错误都会在它们发生后立即被捕获

于 2017-06-13T01:38:00.140 回答
0

既然您使用的是 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 } }
});
于 2016-07-21T16:35:10.947 回答
0

我想出了一个让它工作的方法。

我创建了一个返回 Promise 的函数数组,而不是一组 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));

那正在解决我的问题,但不确定这是否是最好的方法。如果有人有更好的想法,我会接受。

于 2016-07-22T12:25:09.097 回答