Bluebird's Promise.settle doesn't resolve with the correct values

懵懂的女人 提交于 2019-12-12 12:26:28

问题


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.com/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?


回答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've always just used it as a substitute for Promise.all() when you want all promises to complete, 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 completed that implementation.




回答2:


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.



来源:https://stackoverflow.com/questions/26594382/bluebirds-promise-settle-doesnt-resolve-with-the-correct-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!