admin管理员组

文章数量:1391934

I have the following code:

return Promise.settle(matches, imgur.uploadUrl)
    .map(function (inspection) {
        if (inspection.isFulfilled()) {
            return inspection.value().data.link;
        }
        return '#';
    })

A more verbose version of the above displays the same problems:

return Promise.settle(matches, function(match) { return imgur.uploadUrl(match); })
    .then(function(results) {
        return results;
    })
    .map(function (inspection) {
        if (inspection.isFulfilled()) {
            return inspection.value().data.link;
        }
        return '#';
    })

Where

  • Promise = bluebird's promise
  • matches = an array of image links extracted from a string
  • imgur =

The expected behavior is that the result of .map is a promise which resolves with an array of imgur links after the images in the original array was uploaded to imgur (or '#', in case the upload failed for any reason).

What happens instead is that Promise.settle resolves instantly (i.e. doesn't seem to wait for the imgur uploads), and inspection.value() is the original image url from the matches array (which gives an error when trying to read the .data.link property of a string).

Why does this happen? Why won't it upload to imgur and resolve correctly?

I have the following code:

return Promise.settle(matches, imgur.uploadUrl)
    .map(function (inspection) {
        if (inspection.isFulfilled()) {
            return inspection.value().data.link;
        }
        return '#';
    })

A more verbose version of the above displays the same problems:

return Promise.settle(matches, function(match) { return imgur.uploadUrl(match); })
    .then(function(results) {
        return results;
    })
    .map(function (inspection) {
        if (inspection.isFulfilled()) {
            return inspection.value().data.link;
        }
        return '#';
    })

Where

  • Promise = bluebird's promise
  • matches = an array of image links extracted from a string
  • imgur = https://github./kaimallea/node-imgur

The expected behavior is that the result of .map is a promise which resolves with an array of imgur links after the images in the original array was uploaded to imgur (or '#', in case the upload failed for any reason).

What happens instead is that Promise.settle resolves instantly (i.e. doesn't seem to wait for the imgur uploads), and inspection.value() is the original image url from the matches array (which gives an error when trying to read the .data.link property of a string).

Why does this happen? Why won't it upload to imgur and resolve correctly?

Share Improve this question edited Oct 27, 2014 at 18:51 Madara's Ghost asked Oct 27, 2014 at 18:30 Madara's GhostMadara's Ghost 175k50 gold badges272 silver badges314 bronze badges 5
  • I'd suggest simplifying to Promise.settle(matches, imgur.uploadUrl).then(function(results) { ... }) first to see if results contains what you expect so you can see if it's the .settle() not doing what you want or the .map(). – jfriend00 Commented Oct 27, 2014 at 18:42
  • I actually did do that before I got to this exact version of the code, and it didn't do much difference. – Madara's Ghost Commented Oct 27, 2014 at 18:44
  • The point of my ment was for you to explain whether just the .settle() gets the right results or not? Is the issue with .settle() or with .map(). I'm trying to break a plicated problem down into pieces so one knows where to look further for the issue. – jfriend00 Commented Oct 27, 2014 at 18:49
  • 1 When I look at the Bluebird source for Promise.settle(), I only see that it processes the first argument (expecting an array of promises). I wonder if the Bluebird documentation for .settle() is just wrong about it taking a function as the second argument that will process the first array? The code is a little hard to follow, but I don't see how Promise.settle() ever uses the 2nd argument (unless this isn't the right code I'm looking at for some reason). – jfriend00 Commented Oct 27, 2014 at 18:54
  • @jfriend00 Post that as an answer. I refactored to Promise.settle(matches.map(imgur.uploadUrl)) and it worked. I will file a bug with bluebird – Madara's Ghost Commented Oct 27, 2014 at 18:57
Add a ment  | 

2 Answers 2

Reset to default 4

When I look at the Bluebird source for Promise.settle(), I only see that it processes the first argument (expecting an array of promises). I've always just used it as a substitute for Promise.all() when you want all promises to plete, even if some have errors.

I wonder if the Bluebird documentation for .settle() is just wrong about it taking a function as the second argument that will process the first array? The code is a little hard to follow, but I don't see how Promise.settle() ever uses the 2nd argument (unless this isn't the right code I'm looking at for some reason).

As you pointed out, an alternative is:

Promise.settle(matches.map(imgur.uploadUrl)).then(...)

which just passes an array of promises to .settle().


FYI, I verified by creating a simple test case and stepping into Promise.settle() in the debugger that it never uses the second argument passed to it. This appears to be a case of the documentation not matching the implementation. I expect someone planned to implement what is documented, but never pleted that implementation.

This was indeed a bug in the docs. It was fixed (props to OP for the pull request).

The docs now show the correct usage of .settle.

本文标签: javascriptBluebird39s Promisesettle doesn39t resolve with the correct valuesStack Overflow