Promise of promise to simple promise?

2019-07-07 20:16发布

问题:

I've been playing with promises, and usually can figure out how to handle them well, but in this situation, I can't figure out how to remove one promise-wrapping level.

Here is the code:

let promise2 = promise1.then((nodes) => {
  return Promise.all(nodes.map(n => {

    // findConnections returns a promise
    return this.findConnections(n.get("spotifyData")); 
  }));
});

Now I would expect promise2 to wrap an array, but it doesn't, it wraps a promise wrapping an array. If I want to access the array, I have to do this:

promise2.then(level1 => level1.then(level2 => console.log(level2)));

level1 is a promise itself.

Of course, I could work with that, but I find the code very ugly, and I'd like to simplify it so that you can do:

promise2.then(level1 => console.log(level1))

and directly get an array there.

Any ideas ?

Thanks!

EDIT:

The findConnections() method:

findConnections: function (node) {
  return Ember.$.get("https://api.spotify.com/v1/artists/" + node.id + "/related-artists").then((data) => {
     return data.artists;
  });
}

回答1:

level1 is a promise itself.

No it's not. Ember does use RSVP, which is Promises/A+ compatible, and that means that then callbacks are never called with a promise (or thenable). They always receive a plain value.

Promises/A+ does mandate that there are no nested promises returned from then. They are always recursively unwrapped. You can just do

promise2.then(connections => console.log(connections));

If this really doesn't work, that would suggest that promise1 is no real (or at least no standard-conformant) promise, and you should do promise1 = Promise.resolve(promise1) first.