最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

嵌套异步等待Nodejs

运维笔记admin5浏览0评论

嵌套异步/等待Nodejs

嵌套异步/等待Nodejs

似乎无法弄清楚为什么这对我不起作用。我有一个父函数在子加载进程上执行AWAIT ... LOAD进程依次调用另一个叫做LOADDATA的AWAIT ...所以基本上是这样的:

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失败说明:

await 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将工作。
  • 如果按照我的建议重写,则不需要使用Promise对象,因为您正在使用的方法无论如何都会返回promise。
  • 你的原始函数什么都没解析,所以这个函数通过什么都不返回来工作。
  • 您的原始函数也在使用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

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论