最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

处理forEach循环中的promise

IT培训 admin 8浏览 0评论

处理forEach循环中的promise

我正在尝试执行一系列任务。每项任务都是动态的,可能有不同的规则要遵循。这将在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('promise-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。

我尝试过使用map而不是,但最终结果总是一样的。

我究竟做错了什么?

回答如下:

你可以使用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);
}

别忘了让你的功能异步!

处理forEach循环中的promise

我正在尝试执行一系列任务。每项任务都是动态的,可能有不同的规则要遵循。这将在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('promise-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。

我尝试过使用map而不是,但最终结果总是一样的。

我究竟做错了什么?

回答如下:

你可以使用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);
}

别忘了让你的功能异步!

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论