嵌套异步/等待nodejs



似乎无法弄清楚为什么这对我不起作用。我有一个父函数在子负载过程中执行等待...又调用了另一个正在等待的称为LoadData ...因此,基本上是这样:

module.exports = async function () {
    try {
       await load();
    } catch (ex) {
        console.log(ex);
        logger.error(ex);
    }
};
async function load() {
    return await new Promise((resolve, reject) => {
        TableImport.findAll().then((tables) => {
           for (let table of tables) {
                await loadData(table.fileName, table.tableName);
            }
            resolve();
        }).catch(function (err) {
            reject(err);
        })
    })
};

async function loadData(location, tableName) {
    return await new Promise(function (resolve, reject) {
        var currentFile = path.resolve(__dirname + '/../fdb/' + location);
        sequelize.query("LOAD DATA LOCAL INFILE '" + currentFile.replace('/', '//').replace(/\/g, '\\') + "' INTO TABLE " + tableName + " FIELDS TERMINATED BY '|'").then(function () {
            resolve(tableName);
        }).catch(function (ex) {
            reject();
        });
    });
};

负载中的等待失败说明:

等待LoadData(Table.FileName,Table.TableName);SyntaxError:意外的标识符

显然不了解有关异步的范围!

您只能在异步函数的内部使用await。如果您在异步函数内嵌套了非迅速函数,则不能在该函数中使用await

async function load() {
    return await new Promise((resolve, reject) => {
        TableImport.findAll().then((tables) => {
           for (let table of tables) {
               await loadData(table.fileName, table.tableName);

您对上述.then方法有回调。此回调不是异步。您可以通过执行async tables => {

来解决此问题。

但是,由于load是异步,findAll返回承诺,因此您不需要使用.then

async function load() {
    const tables = await TableImport.findAll();
    for (let table of tables) {
        await loadData(table.fileName, table.tableName);
    }
}

我不确定loadData的功能以及是否必须按顺序加载表,但也可以并行化:

const tables = await TableImport.findAll();
const loadPromises = tables.map(table => loadData(table.fileName, table.tableName));
await Promise.all(loadPromises);
  • return await是多余的,因为您已经在返回承诺。只有return可以工作。
  • 如果您按照我的建议重写,则不需要使用承诺对象,因为您正在使用返回承诺的方法。
  • 您的原始功能什么都没有解决,因此该功能通过什么都没有返回。
  • 您的原始功能也在传播reject(err)的错误。此功能在内部无法处理错误,因此它也将以相同的方式传播错误。

您的loadData功能也可以重写并简化了很多:

function loadData(location, tableName) {
    const currentFile = path.resolve(__dirname + '/../fdb/' + location);
    return sequelize.query("LOAD DATA LOCAL INFILE '" + currentFile.replace('/', '//').replace(/\/g, '\\') + "' INTO TABLE " + tableName + " FIELDS TERMINATED BY '|'");
};
  • loadData不需要是异步,因为您不使用await。您仍在返回诺言。
  • 您可能需要添加.catch,因为在原始代码中您没有返回错误。我上面的代码将返回由.query引起的错误。
  • 您将表名称传递到中,而实际上您没有使用返回值进行任何操作,所以我只是完全删除了.then

最新更新