简体   繁体   English

Promise.all()数组

[英]array of promises and Promise.all()

I have this array of Promises like: 我有这样的承诺数组:

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

and I want to execute them all and catch their errors like this 我想全部执行它们,并捕获这样的错误

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

that's working fine but I now want to that in the then() of another promise: 那很好,但是我现在想在另一个promise的then()中做到这一点:

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

this one's works also fine as long as I write the array directly in Promise.all(), but if I want to use promiseArray define earlier like: 只要我直接在Promise.all()中编写数组,此函数的效果也很好,但是如果我想使用promiseArray定义得更早,例如:

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

then, the catch() is run as expected but I have an error in the console 然后, catch()会按预期运行,但控制台中出现错误

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

But I want to use that last solution as my array is generated according to some conditions by pushing the Promises to it. 但是我想使用最后一个解决方案,因为我的数组是根据某些条件通过将Promises推入数组而生成的。 (and the first example is working just fine, I don't get what is different) (第一个示例工作得很好,我没有什么不同)

Adding catch to each of my promises while adding them to the array save my problem, but I'd like to find a better solution. 在将每个promise添加到数组中的同时,将捕获添加到我的每个promise中可以解决我的问题,但是我想找到一个更好的解决方案。

I would really appreciate some help with that. 我真的很感谢您的帮助。

PS: I am using angular2 with zone.js if it changes something PS:如果更改了某些内容,我将在zone2.js中使用angular2

As soon as you execute an async function (one that returns a promise) it begins running the task in the background (kindof) that promise may resolve or reject at any time from the moment you run 一旦执行了异步函数(一个返回诺言的函数),它就会开始在后台运行(种类)任务,该诺言可能会在您运行后的任何时间解析或拒绝

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

these services are going off and loading data, if they return before a .then() is attached, they will hold onto their value and as soon as you call promisesArray[0].then(x => console.log(x)) the then function will be run with that value 这些服务将关闭并加载数据,如果它们在附加.then()之前返回,它们将保持其值,并在您调用promisesArray [0] .then(x => console.log(x))时立即保留。 then函数将使用该值运行

HOWEVER If one of these services throws an error and there is no .catch function attached yet, they will hold onto the error in order to send it to a .catch() function later specified, but they will also throw a console error - because they dont know if there will ever be a catch function attached, and it would be frustrating if promises just silently failed and errors disappeared. 但是,如果这些服务之一引发错误并且尚不附加.catch函数,它们将保留该错误以便将其发送到以后指定的.catch()函数,但是它们还会引发控制台错误-因为他们不知道是否会附加catch函数,如果诺言只是默默地失败并且错误消失了,那将是令人沮丧的。

If you truely want your promisesArray to execute AFTER baseService(), then your idea of making promisesArray an array of functions which kick off an async task and return a promise - is a good one. 如果您确实希望您的promisesArray执行AFTER baseService(),那么您的想法就是使promisesArray成为启动异步任务并返回promise的函数数组。 However it may be nicer to pass in a function which returns an array of promises, rather then passing in an array of functions which return promises (as stated above) 但是,最好传递一个返回一个promise数组的函数,而不是传递一个返回一个promise的函数数组(如上所述)。

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

then execute using 然后执行

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

This will only start your service1.load's after baseServce() has completed, and all errors will be caught as soon as they occour 这只会在baseServce()完成后启动您的service1.load,并且所有错误一旦发生就会被捕获。

Since you're using angular2, why not using Observable and Http . 由于您使用的是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 } }
});

I figured out a way to make it work. 我想出了一种使它起作用的方法。

Instead of an array of promise I make an array of functions that return a Promise: 我创建了一个返回Promise的函数数组,而不是promise数组:

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

Then I use Array.prototype.map() to run the promises in Promise.all() : 然后,我使用Array.prototype.map()Promise.all()运行promises:

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

That is solving my problem, not sure if it's the best way to do it though. 那就是解决我的问题,虽然不确定这是否是最好的方法。 If anyone have a better idea, i'll take it. 如果有人有更好的主意,我会接受。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM