Right now, the parent for-loop (m < repliesIDsArray.length
) completes before the first findOne fires, so this all only loops through the last element of the repliesIDsArray..asynchronous..
What's the proper syntax for a promisified version of this codeset? Am new to promisification, and wondering how to start this promisify + loop through arrays + account for if-statements..
Bluebird is required, and Promise.promisifyAll(require("mongoose"));
is called.
for(var m=0; m<repliesIDsArray.length; m++){
objectID = repliesIDsArray[m];
Models.Message.findOne({ "_id": req.params.message_id},
function (err, doc) {
if (doc) {
// loop over doc.replies to find the index(index1) of objectID at replies[index]._id
var index1;
for(var i=0; i<doc.replies.length; i++){
if (doc.replies[i]._id == objectID) {
index1 = i;
break;
}
}
// loop over doc.replies[index1].to and find the index(index2) of res.locals.username at replies[index1].to[index2]
var index2;
for(var j=0; j<doc.replies[index1].to.length; j++){
if (doc.replies[index1].to[j].username === res.locals.username) {
index2 = j;
break;
}
}
doc.replies[index1].to[index2].read.marked = true;
doc.replies[index1].to[index2].read.datetime = req.body.datetimeRead;
doc.replies[index1].to[index2].updated= req.body.datetimeRead;
doc.markModified('replies');
doc.save();
}
}); // .save() read.marked:true for each replyID of this Message for res.locals.username
} // for loop of repliesIDsArray
The strongest feature of Bluebird is that it allows you to “promisify” other Node modules in order to use them asynchronously. Promisify is a concept applied to callback functions. This concept is used to ensure that every callback function which is called returns some value.
each. Given an Iterable (an array, for example), or a promise of an Iterable , iterates serially over all the values in it, executing the given iterator on each element. If an element is a promise, the iterator will wait for it before proceeding.
map. Given a finite Iterable (arrays are Iterable ), or a promise of an Iterable , which produces promises (or a mix of promises and values), iterate over all the values in the Iterable into an array and map the array to another using the given mapper function.
As Benjamin said, instead of using for
loop, use Promise.each
(or .map
)
Look on the Bluebird API docs here and search "example of static map:". With map
is clearer to understand than docs for each
var Promise = require('bluebird')
// promisify the entire mongoose Model
var Message = Promise.promisifyAll(Models.Message)
Promise.each(repliesIDsArray, function(replyID){
return Message.findOneAsync({'_id': req.params.message_id})
.then(function(doc){
// do stuff with 'doc' here.
})
})
From the docs, .each
(or .map
) takes "an array, or a promise of an array, which contains promises (or a mix of promises and values)
", so that means you can use it with array of 100% pure values to kickoff promise chain
Hope it helps!
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