我有这样的Promises数组,如:
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,如果它改变了什么
答案 0 :(得分:1)
一旦执行异步函数(返回一个promise),它就会开始在后台运行任务(kindof),承诺可以在您运行的那一刻随时解析或拒绝
let promisesArray = [
service1.load('blabla'),
service2.load(), // throws an errors
];
这些服务正在关闭并加载数据,如果它们在附加.then()之前返回,它们将保持其值并且一旦调用promisesArray [0] .then(x => console.log) (x))then函数将以该值
运行但是,如果其中一个服务抛出错误并且还没有附加.catch函数,它们将保留错误以便将其发送到稍后指定的.catch()函数,但它们也会抛出一个控制台错误 - 因为他们不知道是否会附加一个catch函数,如果promises只是默默地失败并且错误消失,那将是令人沮丧的。
如果你真的希望你的promisesArray执行AFTER baseService(),那么你想让promisesArray成为一个启动异步任务并返回一个承诺的函数数组 - 是一个很好的想法。 但是传入一个返回promises数组的函数可能更好,而不是传递一个返回promise的函数数组(如上所述)
const getPromises = () => [
service1.load('blabla'),
service2.load(), // throws an errors
]
然后执行
baseService()
.then(() => Promise.all(getPromises()))
.catch((err) => handleError(err));
这只会在baseServce()完成后启动service1.load,并且所有错误都会在它们出现后立即被捕获
答案 1 :(得分: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 } }
});
答案 2 :(得分: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));
这解决了我的问题,不确定它是不是最好的方法。 如果有人有更好的想法,我会接受它。