【问题标题】:JavaScript Promises - Creating an array of promises to be executed togetherJavaScript Promises - 创建一组要一起执行的 Promise
【发布时间】:2017-01-18 07:37:12
【问题描述】:

我正在使用 Node.js 处理对 noSQL DynamoDB 的异步调用。我首先查询该帐户属于哪个“好友列表”。这可能会从零返回到“n”个新主键,其中将包含每个好友列表的所有成员的列表。把它们想象成一个人所属的俱乐部……你可能没有也可能有很多;每个俱乐部都有几个成员,甚至一个。

到目前为止(我在这里第一次使用 Promises...虽然我在以前的 JA 项目中使用过回调)我对我的位置很好,但我知道我正在组装一系列 Promise错误地。也就是说,我可以在控制台中看到 .then 函数在两个 Promise 解决之前执行。作为记录,我确实希望......任何 .then 都可能对单个承诺解决感到满意,这似乎是合理的。

无论如何,有人可以提供一些关于如何构建的提示吗?我想以伪结尾:

getBuddyLists .then(getAllTheBuddiesInTheLists) .then(function(){//doSomething});

我的 Node.js 代码:

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region:'us-east-1'});
var buddyGroups = [];

exports.handler = function(event, context, callback) {
    var params = {
        TableName: 'USER_INFORMATION',
        Key: {
            "DEVICE_ID": event.DEVICE_ID
        }
    };

    var getBuddyList = new Promise(function(resolve, reject){
        docClient.get(params, function(err, data){
            if(err){
                reject(err);
            }
            else{
                var dataJSON = JSON.parse(JSON.stringify(data));
                dataJSON.Item.my_buddies.values.forEach(function(value){
                    buddyGroups.push(value);
                });
                console.log('Got buddy groups: ' + buddyGroups);
                resolve(buddyGroups);
            }
        });
    });

    getBuddyList.then(function(capturedData){  // capturedData => an array of primary keys in another noSQL document
        console.log('groups: ' + capturedData);
        var myPromises = [];
        capturedData.forEach(function(value){
            var reqParams = {
                        TableName: "buddy_list",
                        Key: {"BUDDY_ID": value}
                    };
            myPromises.push(new Promise (function(resolve, reject){
                docClient.get(reqParams, function(err, data){
                    if(err){
                        //console.log(err, data);
                    reject(err);
                    }else{
                        var returnedJSON = JSON.parse(JSON.stringify(data));
                        console.log(returnedJSON);
                        resolve(returnedJSON);
                    }
                });
            }));
        });
        //
        Promise.all(myPromises); // ADDED IN EDIT <<<<<<<<<<<<<<<<<<<<<<
        // how to make sure all of myPromises are resolved?
        //
    }).then(function(){
            console.log("done");
        })
    .catch(function(err){
        console.log("error message:" + error);
    });
};

编辑:添加了 Promise.all(myPromises);

的位置

【问题讨论】:

  • 不相关,但您应该使用 myPromises = capturedData.map(...) 而不是 .forEach / .push 循环
  • @Alnitak,来自 C++,我很难摆脱 for 循环范式!我想您是因为 .forEach... 的阻塞性质或其他原因而提供的?
  • .forEach 没有“阻塞性”....map 模式更有效...Promise.all(capturedData.map(function(value) { ... return(new Promise ... - 根本不需要myPromises var
  • @JimfromPrinceton 不,它比这更简单 - 如果您有一个数组作为输入,并且想要一个大小相等的数组作为输出(输入元素和输出元素之间的映射为 1:1)然后.map 正是这项工作的正确功能。

标签: javascript node.js promise


【解决方案1】:

只是为了澄清您将如何使用Promise.all,即使您接受了答案,您也编辑了问题,但仍然没有正确使用它

此外,关于 .map 与 .forEach 的讨论 - 这就是您将如何使用 .map

    getBuddyList.then(function(capturedData){  // capturedData => an array of primary keys in another noSQL document
        console.log('groups: ' + capturedData);
        // changes to use .map rather than .forEach
        // also, you need to RETURN a promise - your edited code did not
        return Promise.all(capturedData.map(function(value){
            return new Promise (function(resolve, reject){
                var reqParams = {
                    TableName: "buddy_list",
                    Key: {"BUDDY_ID": value}
                };
                docClient.get(reqParams, function(err, data){
                    if(err){
                        //console.log(err, data);
                    reject(err);
                    }else{
                        var returnedJSON = JSON.parse(JSON.stringify(data));
                        console.log(returnedJSON);
                        resolve(returnedJSON);
                    }
                });
            });
        }));
    }).then(function(){
            console.log("done");
        })
    .catch(function(err){
        console.log("error message:" + error);
    });

【讨论】:

  • 感谢您发布正确的代码...我很感激(以及使用 .map()
【解决方案2】:

您正在寻找Promise.all(myPromises),它返回一个由一系列承诺结果组成的承诺。

【讨论】:

  • 那么,必须在 .then 发生之前解析 .then-able 上下文中包含的所有承诺吗?
  • @AlvMF1 ,我根据上面的编辑添加,但我的日志表明我的 .then 发生在所有承诺解决之前:START RequestId: Version: $LATEST 2017-01-17T23:23:19得到好友组:12345,ABCDE 2017-01-17T23:23:19 组:12345,ABCDE 2017-01-17T23:23:19 在这里完成 2017-01-17T23:23:19 {项目:{ BUDDY_ID:'12345' ,成员:{值:[对象],类型:'字符串'} } } 2017-01-17T23:23:19 {项目:{ BUDDY_ID:'ABCDE',成员:{值:[对象],类型:'字符串' } } } 结束
  • return Promise.all(myPromises);
猜你喜欢
  • 1970-01-01
  • 2019-07-17
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-22
  • 2017-06-22
  • 1970-01-01
相关资源
最近更新 更多