1

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')
    })
})

My Solution

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)

})
2
  • What is Position, and for what values do its setXY methods return promises? Commented Feb 15, 2014 at 20:41
  • What is "reduce iteration" meant to do? Your promises will all get executed in parallel, and it hardly makes sense to fold over them. Commented Feb 15, 2014 at 20:42

2 Answers 2

2
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);
    });
})
Sign up to request clarification or add additional context in comments.

3 Comments

I knew what I was doing was wrong, but figured I would struggle with it instead of asking straight out. I never thought of returning Q.all from the map. Excellent
Notice that you're not exactly returning Q.all(), but the result of calling .then() on the result of Q.all() - which returns a promise for the result (Position.qCreate()) of its callback! (Crazy nesting all this is :-)
yes - exactly. Thank you again - between the nesting and the abstraction it is tricky to keep your head straight.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.