Bluebird Promise串行迭代,并解析为修改过的数组?

Sta*_*cks 9 javascript node.js promise bluebird

我有这个承诺,Item如果在数据库中找不到它,则会创建一个新文档,然后将其存储在以前创建的Collection文档中.

Collection文档是数组中的第一个字符串,数组中的任何后续索引都转换为一个或多个Item文档.

Promise.each "解析为原始数组未修饰的"等等,最后return内的Promise.each被渲染的对象,但在随后.then产生原始阵列..

这是承诺(缩写为可读性):

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;
});
Run Code Online (Sandbox Code Playgroud)

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 } ]
Run Code Online (Sandbox Code Playgroud)

然后在接下来的.then(function(allItems) {这里是最后一个console.log:

allItems: [ 
[ 'collectionName', 'one', 'two' ]
Run Code Online (Sandbox Code Playgroud)

另外,可变itemSeries的是= Promise.each后呈现undefined在Promise.join?

t.n*_*ese 24

.each函数不会更改通过链传递的值:

我简化了你的代码,作为输入我假设:

var items = ['one','two'];
Run Code Online (Sandbox Code Playgroud)

对于你的代码:

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

结果仍然是['one','two']因为这是数组的已解析值items.每个中返回的值不会影响传递给链接的值的内容then.

.map另一方面,该功能将产生这种效果:

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

这里的return值将用于创建一个新数组,然后将其传递给then.结果如下['one.','two.'].

allItems代码中出现的两个是不同的对象.

编辑 对于使用映射的连续迭代,我会编写一个这样的辅助函数:

 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();
 }
Run Code Online (Sandbox Code Playgroud)

来源:实施Promise.series