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

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

问题描述

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

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 中的最后一个 return 正在渲染对象,但随后的 .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;
});

这是 Promise.each 中的最后一个 console.log:

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

此外,= Promise.each 的变量 itemSeries 稍后会在 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 的解析值.each 中的返回值不影响传递给链式 then 的值的内容.

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.

另一方面,.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 值将用于创建一个新数组,然后将其传递给 then.这里的结果是 ['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.'].

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

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

来源:实施 Promise.series

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

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