Reputation: 6888
I cannot seem to get my head around this. I have a list of positions, which I want to turn into an array of promises, which I then want to collect. It is not working, positionPromises results in an array of nulls (e.g. [ null, null ])
var positionPromises = _.map(positions, function(position) {
var newPosition = Position({
'weight': 1
,'ideaId': idea.id
})
var promise = null
Q.all([
// asynchronous sets (each does a db lookup)
newPosition.setDirectionByName(position.direction)
, newPosition.setSecurityByTicker(position.ticker)
]).then(function(noop) {
// the position has it's data, invoke save which also returns a promise
promise = Position.qCreate(newPosition)
}).done()
return promise
console.log("NEVER GET HERE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
}) // _.map
console.log(positionPromises)
positionPromises.reduce(function(noop, positionPromise){
console.log('Reduce iteration')
positionPromise.then(function(position) {
console.log('THEN')
})
})
From the answers below, this is what I am going with...
the reduce in the above attempt was meant t o be the point where I associate the position back with the idea, prior to returning it to the UI. BUT since I am not accumulating anything, ALL works (probably better):
var positionPromises = _.map(positions, function(position) {
var newPosition = Position({
'weight': 1
,'ideaId': idea.id
})
return Q.all([
newPosition.setDirectionByName(position.direction)
, newPosition.setSecurityByTicker(position.ticker)
]).then(function(noop) {
//newPosition.setIdea(idea)
return Position.qCreate(newPosition)
})
}) // _.map
Q.all(positionPromises).then(function(positions){
console.log('RESULTS of POSITION Promises')
idea.positions = positions
res.send(idea)
})
Upvotes: 1
Views: 422
Reputation: 664620
var promise = null Q.all(…) return promise
You are returning null
here from the function. All assignments to the promise
variable are done in asynchronous callbacks, which will occur after the mapping function has returned.
What you need to do instead is using then
for chaining: Compute both setDirectionByName
and setSecurityByTicker
, then when both (all) are done qCreate
a promise, and then yield the value of that promise:
var positionPromises = _.map(positions, function(position) {
var newPosition = Position({
'weight': 1,
'ideaId': idea.id
});
return Q.all([
newPosition.setDirectionByName(position.direction),
newPosition.setSecurityByTicker(position.ticker)
]).then(function() {
return Position.qCreate(newPosition);
});
})
Upvotes: 2
Reputation: 12961
when you do:
...).then(function(noop) {
// the position has it's data, invoke save which also returns a promise
promise = Position.qCreate(newPosition)
});
it doesn't get called at the time, because it is a async call, so you get nulls array.
Upvotes: 0