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 promisematches
= an array of image links extracted from a stringimgur
= 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?
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With