简体   繁体   中英

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?

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.

Here is how I'd write it, I'm using ES6 code through Babel in my bluebird.

import {props, map} from "bluebird";

map(xs, x => props({x, y:square(x)}); // do something with it :)

This uses Promise.props for waiting for properties of an object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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