如何链接从nodejs中的多个文件返回的承诺

时间:2018-10-05 06:21:33

标签: node.js aws-lambda es6-promise bluebird

我正在尝试编写Lambda代码,在该代码中尝试在DynamoDB中输入多个条目,如果失败,则会在SQS中输入错误消息。我正在尝试使用Promises来做到这一点。

我的DDB.js文件

var AWS = require('aws-sdk');

exports.operation = function(ddbEvent) {
    var dynamoDB = new AWS.DynamoDB();
    var params = {};

    var operation = ddbEvent.operation;
    switch(operation) {
        case 'insert':
        case 'modify':
            params["Item"] = ddbEvent.entry;
            //Fill in params object from ddbEvent;

            return dynamoDb.putItem(params, function(err, data) {
                //Nothing to do just log
                if(err) {
                    //log error msg
                } else {
                    //log success
                }
            }).promise();

        case 'delete':
            //Do nothing operation
            return Promise.resolve();

        default:
            console.warn("unsupported");
    }
};

我的SQS.js文件:

var AWS = require('aws-sdk');

exports.sqsOperation = function(message) {
    var sqs = new AWS.SQS({

    });

    var params = {
        //Use message to form the body
    };

    return sqs.sendMessage(params, function(err, data) {
        //Nothing to do just log like in DDB.js
    }).promise();
};

我的main.js文件(调用了Lambda):

var AWS = require('aws-sdk');
var SQS = require('SQS');
var DDB = require('DDB');


    exports.replicate = function(event, context, callback) {
        var ddbPromise = [];
        var sqsPromise = [];

        event.Records.forEach((entry) => {
            let p = DDB.operation(entry);
            ddbPromise.push(p);
            p.then(function(data) {
                //write to ddb succssfull;
            }).catch(function (err) {
                //ddb save failed, try writing to sqs.
                let sqsP = SQS.sqsOperation(entry);
                sqsPromise.push(sqsP);
                sqsP.then(function (data) {
                    //push to sqs success
                }).catch(function (err) {
                    //push to sqs failed
                });
            });
        });

        var ddb_promises_all = Promise.all(ddbPromise);

        ddb_promises_all.then(function (data) {
            //all entries saved in DDB 
            callback(null, "success");
        }).catch(function (err) {
            //Now repeat wait for all sqs promises. If any sqs push failed then
            //use callback(new Error("error"));
        });
    }

可以看出,promise和回调模式混合在一起。我遇到了一个叫做bluebird的图书馆,它可以帮助避免这个问题。那会是更好的方法吗?是否有更好的方法将这些诺言链接起来,因为我觉得将状态保存在数组中似乎是错误的方法,并且如果使用蓝鸟,则强制从回调模式返回诺言将变得更加整洁。

2 个答案:

答案 0 :(得分:1)

异步等待救援 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

async function doDBStuff (...)
async function doOtherStuff (...)

async function doSequentially () {
  await doDBStuff(...);
  await doOtherStuff(...);
}

async function doInParallel () {
  await Promise.all([doDBStuff(...), doOtherStuff(...)]);
}

答案 1 :(得分:1)

对于您的情况,我更喜欢以某些方法将其提取

exports.replicate = function(event, context) {
  // if possible, use Promise for consistency
  return new Promise((resolve, reject) => {

    // I feel that using `map` is cleaner than `forEach`
    const ddbOperationPromises =  event.Records.map(entry => ddbOperation(entry));

    return Promise.all(ddbOperationPromises)
      .then(data => {
        // success
        resolve();
      })
      .catch(err => {
        // catch error
      })
  });
}

function ddbOperation(entry) {
  return DDB.operation(entry)
    .then((data) => {
      // success
    })
    .catch((err) => {
      return sqsOperation(entry);
    })
}

function sqsOperation(entry) {
  return SQS.sqsOperation(entry)
    .then((data) => {
      // success
    })
    .catch((err) => {
      // handling err
    })
}