Sequential iteration of Bluebird Promise and permission to modify the array?

I have this promise that creates a new Item document if it is not found in db and then saves it in a previously created Collection document.

The Collection document is the first line in the array, and any subsequent index in the array is converted to one or more document documents.

Promise.each " Resolves the original array unchanged" , and so the last return in Promise.each renders the objects, but the subsequent .then creates the original array.

Here's the promise (short for readability):

 globalVar = true; collectionId = ""; var itemSeries = Promise.each(items, function(element) { if (globalVar == true) { return Models.Collection.findOneAsync({ "name": element }) .then(function(collection) { // promise chain similar to the following else.. // set the collectionId var to an _id }); } else { return Models.Items.findOneAsync({ "name": element }) .then(function(item) { if (item == null) { return Models.Labels.findOneAsync({ "title": element }) .then(function(label) { var newItem = new Models.Items({ name: element, label: label._id }); return newItem.saveAsync(); }).then(function() { return Models.Items.findOneAsync({ "name": element }); }).then(function(item) { item.collection = collectionId; return item.saveAsync(); }).then(function() { return Models.Items.findOneAsync({ "name": element }); }).then(function(item) { allItems.push(item); console.log("allItems: [ "); console.log(allItems); return allItems; }); } }); } }).then(function(allItems) { console.log("allItems: [ "); console.log(allItems); return allItems; }); 

And here is the last of console.log in Promise.each:

 allItems: [ [ { _id: 54eec5f2b9fb280000286d52, name: 'one', label: 54eec5f2b9fb280000286d51, collection: 54eec5f2b9fb280000286d50, __v: 0 }, { _id: 54eec5f2b9fb280000286d54, name: 'two', label: 54eec5f2b9fb280000286d53, collection: 54eec5f2b9fb280000286d50, __v: 0 } ] 

And then after the subsequent .then(function(allItems) { here is the last console.log :

 allItems: [ [ 'collectionName', 'one', 'two' ] 

Also, the itemSeries variable, which = Promise.each later displays undefined in Promise.join?

+8
javascript promise bluebird
source share
2 answers

The .each function .each not change the value that is passed along the chain:

I have simplified your code since I assume:

 var items = ['one','two']; 

For your code:

 Promise.each(items, function(element) { return element+'.'; //return Promise.resolve(element+'.'); }) .then(function(allItems) { console.dir(allItems); }); 

The result will be ['one','two'] , because these are the allowed values โ€‹โ€‹of the items array. The return value inside each does not affect the contents of the value passed to the then chain.

The .map function, on the other hand, will have this effect:

 Promise.map(items, function(element) { return element+'.'; //return Promise.resolve(element+'.'); }) .then(function(allItems) { console.dir(allItems); }); 

Here, the return value will be used to create a new array, which will then be passed to then . Here the result will be ['one.','two.'] .

The two allItems appearing in your code are different objects.

EDIT For sequential iteration with a mapping, I would write a helper function as follows:

  function mapSeries(things, fn) { var results = []; return Promise.each(things, function(value, index, length) { var ret = fn(value, index, length); results.push(ret); return ret; }).thenReturn(results).all(); } 

Source: Implementing Promise.series

+20
source share

Bluebird now implements mapSeries , see http://bluebirdjs.com/docs/api/promise.mapseries.html

It looks like Promise.each is still returning the original array, unfortunately in v3.xx

+1
source share

All Articles