嵌套异步/等待Nodejs

时间:2017-12-21 16:25:23

标签: node.js asynchronous async-await

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

sp <- ggplot(mpg, aes(hwy, cty)) +
  geom_point() +
  theme_classic() +
  annotate("text", label = "top", 
           x = 0.5*(min(mpg$hwy) + max(mpg$hwy)), y = max(mpg$cty), vjust = 1) +
  annotate("text", label = "bottom", 
           x = 0.5*(min(mpg$hwy) + max(mpg$hwy)), y = min(mpg$cty), vjust = 0) +
  annotate("text", label = "right", 
           x =  max(mpg$hwy), y = 0.5*(min(mpg$cty) + max(mpg$cty)), hjust = 1) +
  annotate("text", label = "left", 
            x =  min(mpg$hwy), y = 0.5*(min(mpg$cty) + max(mpg$cty)), hjust = 0)

sp   

LOAD中的AWAIT未能说明:

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

显然不了解异步的范围!

1 个答案:

答案 0 :(得分:7)

您只能在异步功能中使用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