异步函数返回未定义/挂起的承诺,但在代码中不允许等待

时间:2021-03-09 19:01:47

标签: javascript asynchronous async-await

我已经查看了类似的问题,但没有找到能够在我自己的代码中实现的解决方案,因此我发表了这篇文章。我有以下代码:

async function getProgram(id) {
    let study = "";
    pool.query('SELECT name FROM Programs WHERE id=?', [id], (error, result) => {
      if (error) return console.error(error); // If error, show error in console (in red text) and return
      console.log(result[0].name);
      return result[0].name;
    });
    
    return study;
}

let program = (id) => {
  await getProgram(id)
    .then(study => {
        return study;
    })
    .catch(error => {
      console.error(error);
    });
}

console.log(program(2));

最后一个 console.log 返回 undefined,尽管 pool.query 中的控制台日志给出了我正在寻找的正确字符串。我尝试过的此代码的另一个版本使 Promise 挂起而不是未定义。

通过阅读其他帖子,我理解这是因为我没有在某处使用 await 和 async 函数。问题是,如果我尝试在最后一个 console.log 中插入 await:console.log(await program(2)); 或在程序函数中:let program = (id) => { await getProgram(id) ... 我收到一个错误,告诉我 Unexpected reserved word 'await'

我对 promises/async/await 还是很陌生,所以我确定我遗漏了一些基本的东西..谢谢大家的帮助。

1 个答案:

答案 0 :(得分:0)

您只能在异步函数中使用 await。你应该这样定义程序:

let program = async (id) => {
  await getProgram(id)
    .then(study => {
        return study;
    })
    .catch(error => {
      console.error(error);
    });
}

接下来,现在 program 是一个 promise,console.log(program(2)) 不会打印已解决的 promise。为此,您需要使用其他一些语法,例如:

program(2).then(result => console.log(result));

必须这样做,因为 await 不能用于顶级代码(至少不是在所有浏览器/节点引擎中)。

最后,我认为你也应该将 getProgram 重写如下:

function getProgram(id) {
    return new Promise((resolve,reject) => {
        pool.query('SELECT name FROM Programs WHERE id=?', [id], (error, result) => {
            if (error) {
                console.error(error); // If error, show error in console (in red text) and return
                reject(error)
            }
            console.log(result[0].name);
            resolve(result[0].name);
       });
    });
}

注意 study 没有做任何事情以及您需要如何将池异步函数转换为承诺