【问题标题】:Why await statement is not working in new promise constructor为什么 await 语句在新的 Promise 构造函数中不起作用
【发布时间】:2023-03-28 20:19:01
【问题描述】:

下面的代码给了我错误 SyntaxError: await 仅在异步函数和模块的顶层主体中有效。 我不知道我在这里错过了什么。

function timeout(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function test(num) {
    return new Promise((resolve, reject) => {
        await timeout(1000);
        if (num == 11) {
            reject("error");
        }
        else {
            resolve("completed");
        }
    });
}
test(11).then((val) => { console.log(val) }).catch((err) => { console.log(err) });

【问题讨论】:

  • promise 中的回调函数不是异步的,所以显然你不能在其中使用 await。如果它是一种反模式,您可以通过在 Promise (async (resolve, reject) => {}) 中的匿名回调前面添加 async 关键字来修复它
  • (resolve, reject)async (resolve, reject)
  • 非常感谢。它解决了。所以,如果我是正确的,它会检查上一层函数是否异步。
  • @RohitKumar 它检查当前函数,是的。

标签: javascript node.js


【解决方案1】:

因为您尝试在其中使用它的函数(您传递承诺构造函数的 promise 执行器 函数)不是 async 函数(并且几乎不应该是曾经)。 await 运算符仅存在于 async 函数中。承诺执行者的工作是启动承诺将报告完成的异步进程。如果这样做涉及使用现有的承诺(这将是您使用 async 函数的原因,因此您可以使用 await 它),您根本不使用 new Promise;你锁住了你已经拥有的承诺。 (更多在Is it an anti-pattern to use async/await inside of a new Promise() constructor? 的答案中。剧透:是的,是的。:-D)在你的例子中,你只需使用来自timeout 的承诺,就像这样:

function timeout(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}
async function test(num) {
    await timeout(1000);
    if (num == 11) {
        throw "error"; // (Best practice is to use `new Error` here)
    }
    return "completed";
}
test(11).then((val) => { console.log(val) }).catch((err) => { console.log(err) });

关于该代码的几点说明:

  • 要拒绝async 函数隐式创建的承诺,您要么throw 要么返回一个被/将被拒绝的承诺。更多信息在这里:How to reject in async/await syntax?。这就是我在上面使用throw "error"; 所做的。
  • 要履行async 函数隐式创建的承诺,您需要return 一个值(上面的return "completed")。 (更一般地说:为了解决这个承诺,你使用return,它要么用一个值来实现它,要么在你返回一个值时让它遵循另一个承诺。我在我的博客文章@987654323中关于这个术语@.)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    相关资源
    最近更新 更多