I have this promise that creates a new Item
document if it's not found in the db, and then stores it in a previously created Collection
document..
The Collection document is the first string in an array, and any subsequent index in the array translates to one or more Item docs.
Promise.each "Resolves to the original array unmodified" and so the last return
within the Promise.each
is rendering the objects, but the subsequent .then
produces the original array..
Here's the promise (abbreviated 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's the last of the console.log
within the 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's the last console.log
:
allItems: [
[ 'collectionName', 'one', 'two' ]
Also, the variable itemSeries
that = Promise.each
later renders undefined
in a Promise.join?
The .each
function will not change the value that is passed through the chain:
I simplified your code, as input 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 still be ['one','two']
because this are resolved values of the array items
. The returned value within the each does not influence the content of the value passed to the chained then
.
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 value will be used to create a new array which will then be passed to the then
. Here the result would be ['one.','two.']
.
The two allItems
appearing in your code are different objects.
EDIT For serially iteration with mapping I would write a helper function like this:
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: Implement Promise.series
Bluebird now natively implements a mapSeries
, see http://bluebirdjs.com/docs/api/promise.mapseries.html
It also looks like Promise.each
still returns the original array unfortunately in v3.x.x.
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