嵌套的异步/等待Node.js [英] Nested Async/Await Nodejs

查看:102
本文介绍了嵌套的异步/等待Node.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎无法弄清楚为什么这对我不起作用.我有一个对子加载过程执行AWAIT的父函数... LOAD进程又调用了另一个称为LOADDATA的AWAIT ...因此基本上是这样的:

Cannot seem to figure out why this is not working for me. I have a parent function that performs an AWAIT on a child load process... the LOAD process in turn calls another AWAIT called LOADDATA... so basically like this:

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

LOAD中的AWAIT失败说明:

the AWAIT in the LOAD fails stating:

等待loadData(table.fileName,table.tableName); SyntaxError:意外的标识符

await loadData(table.fileName, table.tableName); SyntaxError: Unexpected identifier

显然不了解异步范围!

推荐答案

您只能在异步函数内部使用await.如果您有一个嵌套在异步函数内部的非异步函数,则不能在该函数中使用await:

You can only use await inside of an async function. If you have a non-async function nested inside of an async function, you can't use await in that function:

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 => {来解决此问题.

You have a callback to the .then method above. This callback is not async. You could fix this by doing async tables => {.

但是,由于load是异步的,并且findAll返回了诺言,因此您无需使用.then:

However since load is async and findAll returns a promise, you don't need to use .then:

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

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

I'm not exactly sure what loadData does and if you have to load the tables in order, but you can also parallelize this:

const tables = await TableImport.findAll();
const loadPromises = tables.map(table => loadData(table.fileName, table.tableName));
await Promise.all(loadPromises);

  • return await是多余的,因为您已经在返回承诺.只需return即可使用.
  • 如果按照我的建议进行重写,则无需使用Promise对象,因为无论如何,使用返回承诺的方法都是如此.
  • 您的原始函数没有解决任何问题,因此该函数通过不返回任何内容而工作相同.
  • 您的原始功能还传播了reject(err)错误.此函数不会在内部处理错误,因此也会以相同的方式传播错误.
    • The return await is superfluous since you are already returning a promise. Just return will work.
    • If you rewrite as I suggested, you don't need to use a Promise object since the methods you are working with return promises anyway.
    • Your original function was resolving nothing, so this function works the same by returning nothing.
    • Your original function was also propagating an error with reject(err). This function does not handle an error internally so it will also propagate the error in the same way.
    • 您的loadData函数也可以重写和简化很多:

      Your loadData function can also be rewritten and simplified quite a bit:

      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.
        • loadData doesn't need to be async since you don't use await. You are still returning a promise.
        • You may want to add .catch since in your original code you didn't return an error. My code above will return the error caused by .query.
        • You pass the table name in and you don't actually do anything with the return value, so I just removed the .then entirely.
        • 这篇关于嵌套的异步/等待Node.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆