использование вложенных async.forEachSeries и async.waterfall для управления последовательностью кода Lambda Node.js

У меня есть часть навыка Alexa, работающего в Lambda, который отправляет текст игроку. Я использую async.waterfall для управления последовательностью обращений к таблице Dynamodb, чтобы получить правильный ARN для этого игрока (куда отправить текст), а затем опубликовать SMS через AWS SNS. Если в playerToReceive[] есть только 1 игрок, это работает. Однако мне нужно, чтобы он работал для нескольких игроков. Для этого я вложил async.waterfall в async.forEachSeries (также пробовал forEach), но у меня неправильная структура обратного вызова. Я думаю, мне нужно применить логику этого ответа, но я Я новичок во многом из этого и изо всех сил.

        async.forEachSeries(    playersToReceive, // array of items             
            function(receivingPlayer, callback){                
                async.waterfall([                   
                    function (callback) {
                        session.attributes.phoneKey = receivingPlayer;
                        callback(null);
                    },                      
                    function (callback) {                   
                        playerStorage.loadPlayer(session, function (newLoadedPlayer) {
                            if (newLoadedPlayer == 'playerNotFound' || newLoadedPlayer == 'errorLoadingPlayer') {
                                problems = true; // set problems flag for later
                                callback(null);
                            } else {
                                var ARNtoSend = newLoadedPlayer.data.TopicARN.S;
                                callback(null, ARNtoSend);
                            };
                        })
                    },                              
                    function (ARNtoSend, callback) {
                        playerSMS.publishSMS(ARNtoSend, textToSend, function (success) {
                            if (success == false) {problems = true}; // set problems flag for later
                            callback(null);
                        })                                                      
                    }                                                       
                ], function (err, result) {
                    if (err) console.log(err, "SMS text had a problem sending.");
                    if (!err) console.log(null, "SMS text was successfully sent.");
                });                                                                                 
                callback();
            },          
            function(err){
                // All tasks are now complete               
                speechText = 'OK, text sent.';
                if (problems == true) {
                    speechText += ' . But there was a problem sending it to some players.'
                }
                response.tell(speechText);                                                                                                                      
            }
        );

person Dana    schedule 23.02.2016    source источник


Ответы (1)


Я понял - внешний обратный вызов должен идти внутри функции закрытия водопада. С этим изменением все работает:

            async.forEachSeries(    playersToReceive, // array of items 

            function(receivingPlayer, callback){

                async.waterfall([

                    function (callback) {
                        session.attributes.phoneKey = receivingPlayer;
                        callback(null);
                    },

                    function (callback) {                   
                        playerStorage.loadPlayer(session, function (newLoadedPlayer) {
                            if (newLoadedPlayer == 'playerNotFound' || newLoadedPlayer == 'errorLoadingPlayer') {
                                problems = true; // set problems flag for later
                                callback(null);
                            } else {
                                var ARNtoSend = newLoadedPlayer.data.TopicARN.S;
                                callback(null, ARNtoSend);
                            };
                        })
                    },

                    function (ARNtoSend, callback) {
                        playerSMS.publishSMS(ARNtoSend, textToSend, function (success) {
                            if (success == false) {problems = true}; // set problems flag for later
                            callback(null);
                        })                                                      
                    }       


                ], function (err, result) {
                    if (err) console.log(err, "SMS text had a problem sending.");
                    if (!err) console.log(null, "SMS text was successfully sent.");
                    callback();
                });                     

            },          

            function(err){
                // All tasks are now complete               
                speechText = 'OK, text sent.';
                if (problems == true) {
                    speechText += ' . But there was a problem sending it to some players.'
                }
                response.tell(speechText);                                                                                                                      
            }
        );  
person Dana    schedule 23.02.2016