Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve a set of promises and values using Bluebird

I have a list values

xs = [1, 2, 3, 4]

I also have an asynchronous function square that returns a promise of the square of the argument passed to it. I want to pass the elements of my to list to my function in parallel, then collect the promises into an array and wait for them all to complete. I can formulate this as a map/reduce operation.

Promise
.map(xs, function(x) {
        return square(x)
    }
)
.reduce(function(ys, y) {
        return ys.concat(y)
    }, [])

This eventually returns the resolved values

[1, 4, 9, 16]

Easy enough. Now say I want to include the original argument in the answer array like so.

[{x:1, y:1}, {x:2, y:4}, {x:3, y:9}, {x:4, y:16}]

The tricky part is now I have a list of objects, each of which at the beginning of the reduce step has a promise buried in its y property. How do I write the Bluebird code to do this reduce step?

like image 249
W.P. McNeill Avatar asked Feb 11 '23 04:02

W.P. McNeill


1 Answers

You wouldn't write this in the reduce step. Put it in the map step instead:

Promise.map(xs, function(x) {
    return f(x).then(function(y) {
        return {x:x, y:y};
    });
})

In fact, you wouldn't have any reduce step at all, because map does already collect the results in an array.

Of course, you could split this in two and flatten your code by doing

Promise.map(xs, f).map(function(y, i) {
    return {x:xs[i], y:y};
})

but I don't think that xs[i] thing is much better.

like image 174
Bergi Avatar answered Feb 12 '23 18:02

Bergi