Bluebird Promise串行迭代,并解析为修改过的数组? [英] Bluebird Promise serial iteration, and resolve to modified array?

查看:115
本文介绍了Bluebird Promise串行迭代,并解析为修改过的数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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..

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

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 解析为未修改的原始数组,因此 Promise.each 中的最后一个返回渲染对象,但后续的 .then 生成原始数组..

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;
});

这是 console.log 在Promise.each中:

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 } ]

然后在后续的 .then(function(allItems){这里是最后的 console.log

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

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

此外,变量 itemSeries = Promise.each 稍后在Promise.join中呈现 undefined

Also, the variable itemSeries that = Promise.each later renders undefined in a Promise.join?

推荐答案

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

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'];

代码:

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

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

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.

<另一方面,code> .map 函数会产生这种效果:

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);
});

此处将使用 return 值创建一个新数组,然后将其传递给然后。这里的结果是 ['one。','two。']

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.'].

两个<$ c您的代码中出现的$ c> allItems 是不同的对象。

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

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();
 }

资料来源:实施Promise.series

这篇关于Bluebird Promise串行迭代,并解析为修改过的数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆