Как связать обещания, возвращенные из нескольких файлов в nodejs - PullRequest
0 голосов
/ 05 октября 2018

Я пытаюсь написать лямбда-код, в котором я пытаюсь сделать несколько записей в 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, которая может помочь избежать этой проблемы.Будет ли это лучше?Есть ли лучший способ связать эти обещания, так как я чувствую, что сохранение состояний в массиве кажется неправильным способом, так как принудительное возвращение обещания из шаблона обратного вызова было бы лучше, если бы использовалась bluebird.

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

В вашем случае я предпочитаю извлекать их некоторыми способами, такими как

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
    })
}
0 голосов
/ 05 октября 2018

асинхронные ожидают спасения 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(...)]);
}
...