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
=
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 promisematches
= an array of image links extracted from a stringimgur
= 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 ifresults
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 howPromise.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
2 Answers
Reset to default 4When 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
.