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

How to chain promises returned from multiple files in nodejs

我正在尝试编写 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"));
        });
    }

可以看出,混合了承诺和回调模式。我遇到了一个名为 bluebird 的库,它可以帮助避免这个问题。那会是更好的方法吗?有没有更好的方法来链接这些承诺,因为我觉得将状态保存在数组中似乎是一种错误的方法,并且如果使用蓝鸟,则强制 return 来自回调模式的承诺会更整洁。

异步等待救援 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(...)]);
}

对于你的情况,我更喜欢用一些方法来提取它们,比如

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