javascript Bluebird Promise 串行迭代,并解析为修改后的数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28736452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bluebird Promise serial iteration, and resolve to modified array?
提问by Stacks
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..
我有这个承诺,Item
如果在数据库中找不到它,它会创建一个新文档,然后将它存储在以前创建的Collection
文档中。
The Collection document is the first string in an array, and any subsequent index in the array translates to one or more Item docs.
Collection 文档是数组中的第一个字符串,数组中的任何后续索引都会转换为一个或多个 Item 文档。
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..
Promise.each “解析为原始数组未修饰的”等等,最后return
内的Promise.each
被渲染的对象,但在随后.then
产生原始阵列..
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:
这console.log
是 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
:
然后在接下来的.then(function(allItems) {
这里是最后一个console.log
:
allItems: [
[ 'collectionName', 'one', 'two' ]
Also, the variable itemSeries
that = Promise.each
later renders undefined
in a Promise.join?
另外,可变itemSeries
的是= Promise.each
后呈现undefined
在Promise.join?
回答by t.niese
The .each
function will not change the value that is passedthrough the chain:
该.each
函数不会更改通过链传递的值:
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
.
结果仍然是['one','two']
因为这是数组的解析值items
。each 中的返回值不会影响传递给 chained 的值的内容then
。
The .map
function on the other hand will have this effect:
.map
另一方面,该功能将具有以下效果:
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.']
.
这里的return
value 值将用于创建一个新数组,然后将其传递给then
. 这里的结果是['one.','two.']
。
The two allItems
appearing in your code are different objects.
allItems
出现在您的代码中的两个是不同的对象。
EDITFor 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
回答by Adam Reis
Bluebird now natively implements a mapSeries
, see http://bluebirdjs.com/docs/api/promise.mapseries.html
Bluebird 现在本地实现了mapSeries
,请参阅http://bluebirdjs.com/docs/api/promise.mapseries.html
It also looks like Promise.each
still returns the original array unfortunately in v3.x.x.
Promise.each
不幸的是,在 v3.xx 中看起来仍然返回原始数组