Обработка обещаний внутри цикла forEach - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь выполнить ряд задач.Каждая задача является динамичной и может иметь разные правила для подражания.Это будет выполнено в AWS-Lambda.

У меня есть массив JSON.У него есть тело с именем задачи и атрибуты.

Мне нужно динамически загрузить файл javascript с именем внутри тела .Мне нужно подождать, пока все не закончится внутри этой задачи.Или это не удалось (независимо от того, где).Если произойдет сбой, мне нужно будет записать эти данные в текущую запись в цикле forEach.

У меня есть старая проблема, когда мой forEach завершается первым, не дожидаясь завершения задачи.Это цикл forEach:

const jobLoader = require('./Helpers/jobLoader');

event.Records.forEach(record => {
    const { body: jobName } = record;
    const { messageAttributes } = record;

    const job = jobLoader.loadJob(jobName);

    job.runJob(messageAttributes).then(res => {
        console.log('Show results');
        return; // resume another record from forEach
    }).catch(err => {
         record.failed = true;
         record.failureMessage = err.message;
        console.log('I errored');
    });

    console.log('All Done');
});

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

Этот файл загружает задачу:

exports.loadJob = (jobName) => {
    const job = require(`../Tasks/${jobName}`);

    return job;
};

Этот файл содержит текущую задачу: const mySqlConnector = require ('../ Storage / mySql');

exports.runJob = async (params) => {
  let payload = {};

    let dataToSend = await getUserName(params.userId.stringValue);

    payload.dataToSend = dataToSend;

    let moreDataToSend = await getEvenMoreData(params.userId.stringValue);

    payload.moreDataToSend = moreDataToSend;

    return await sendData(payload);
};

const getUserName = async (userId) => {
    const query = 'SELECT * FROM user_data';
    return await mySqlConnector.handler(query);
};

const getEvenMoreData = async (userId) => {
    const query = 'SELECT * FROM user_data';
    return await mySqlConnector.handler(query);
};


const sendData = (payload) => {

  //this should be Axios sending data
};

И это сам разъем mySql: const mysql = require ('обещание-mysql');

exports.handler = async (query) => {
   return mysql.createConnection({
        host     : '127.0.0.1',
        user     : 'root',
        password : '',
        database: 'crm'
    }).then(conn =>{
        let result = conn.query(query);
        conn.end();
        return result;
    }).then(rows => {
        //console.log("These are rows:" + rows);
        return rows;
    }).catch(error => {
        return error;
    });
};

В файле задачи может быть любое количество вещей, необходимых для выполнения,который будет другим, когда я начну добавлять задачи.Мне нужно, чтобы задание job.runJob было завершено или оно отлавливало ошибку из любого места, откуда оно возникло, поэтому я могу продолжить работу с forEach.

Я пробовал использовать карту, а что нет, но конечный результат всегдато же самое.

Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Мне удалось ее решить, и до сих пор хранятся подробности о выполнении:

Примерно так:

for (let prop in event.Records){

        const { body: jobName } = event.Records[prop];
        const { messageAttributes } = event.Records[prop];

        const job = jobLoader.loadJob(jobName);

        await job.runJob(messageAttributes).then(res => {
            console.log('Show results', res);
        }).catch(err => {
            event.Records[prop].failed = true;
            event.Records[prop].failed = err.message;
            console.log('I errored');
        });

    }
0 голосов
/ 14 февраля 2019

Вы можете использовать Promise.all метод:

const promises = event.Records.map(record => {
    const { body: jobName } = record;
    const { messageAttributes } = record;

    const job = jobLoader.loadJob(jobName);

    return job.runJob(messageAttributes).then(res => {
        console.log('Show results', res);
    }).catch(err => {
         record.failed = true;
         record.failureMessage = err.message;
        console.log('I errored');
        throw new Error('Your error !');
    });
});

try {
   const results = await Promise.all(promises);
   console.log('All done');
} catch (e) {
   console.log('Something has an error', e);
}

не забудьте сделать вашу функцию асинхронной!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...