如何不忘记在 Javascript 中到处使用 await?

IT技术 javascript asynchronous async-await
2021-03-09 02:50:01

试图写一个小小的chrome扩展,它依赖于接口的回调重查询功能chrome.*,我很快就登陆了promise和async/await,因为我需要保证某些操作的顺序,同时尽量避免回调地狱

但是,一旦我将 async/await 引入某些函数,使用它们的每个函数也必须转换为 anasync function才能await返回值。最终甚至一些全局常量也变成了 promises,例如

const DEBUG = new Promise(function(resolve){
    chrome.management.getSelf(resolve);
}).then(function(self){
    return self.installType == 'development';
});

然而,现在我需要await到处,并且引入像if(DEBUG){...}总是被执行这样的奇怪错误变得太容易了。

虽然似乎可以使用 ESLINT 识别错误,但await到处似乎不必要地麻烦,因此我想知道Javascript 是否有一些我遗漏的更好的构造?

(主观上,我目前对 await/async 的使用似乎倒退了;除非明确等待,否则 Promise 将保持原样,但我似乎更希望在异步函数中默认等待 Promise 并且仅在明确请求时才将其保留为裸Promise。)

1个回答

由于缺乏可以轻松捕获此类错误的类型系统(您考虑过 Typescript 还是 Flow?),您可以使用Systems Hungarian Notation作为您的变量名称。选择后缀的前缀,如P, Promiseor$并将其添加到所有Promise变量中,类似于通常使用Async后缀命名异步函数的方式然后只做类似的事情

const debug = await debugPromise

你可以很快看到这if (debug)很好,但if (debugPromise)不是。


一旦我将 async/await 引入某些函数,使用它们的每个函数也必须转换为 async 函数,以便能够等待返回值。最终甚至一些全局常量也变成了 promise

我不会那样做。尝试使尽可能少的函数异步。如果他们自己没有做本质上异步的事情,而只是依赖一些Promise的结果,那么将这些结果声明为函数的参数。一个简单的例子:

// Bad
async function fetchAndParse(options) {
    const response = await fetch(options);
    // do something
    return result;
}
// usage:
await fetchAndParse(options)

// Good:
function parse(response) {
    // do something
    return result;
}
// usage:
await fetch(options).then(parse) // or
parse(await fetch(options))

相同的模式可以应用于全局变量 - 使它们成为每个函数的显式参数,或者使它们成为包含所有其他函数的module函数的参数作为闭包。然后await全局Promise在module中只Promise一次,在声明或执行其他任何东西之前,然后使用普通的结果值。

// Bad:
async function log(line) {
    if (await debugPromise)
        console.log(line);
}
async function parse(response) {
    await log("parsing")
    // do something
    return result;
}
… await parse(…) …

// Good:
(async function mymodule() {
    const debug = await debugPromise;
    function log(line) {
        if (debug)
            console.log(line);
    }
    function parse(response) {
        log("parsing")
        // do something
        return result;
    }
    … parse(…) …
}());
@StephenCleary 谢谢,我已经想知道我是否应该澄清人们不会对 promise 变量和异步函数使用相同的后缀。
2021-04-18 02:50:01
谢谢贝尔吉。解释得很清楚。这很好。还有两种情况 - 1) 在使用 Promise 的 async/await 期间出错。2) 使用 async/await 进行 promise 时拒绝使用问题。您如何遵循处理 async/await 中的错误的良好做法?其次,在异步/等待Promise时处理拒绝代码的好方法是什么?任何参考或代码示例都可以
2021-05-06 02:50:01
关于命名,Async后缀很常见;这是一个.NET 约定,但也被 Bluebird 采纳
2021-05-08 02:50:01
@FrankNocke“可以被视为”几乎没有意义。他们Promise:-)
2021-05-14 02:50:01
@Gary像其他地方一样使用try/ catch或者根据您的需要进行一些变化
2021-05-15 02:50:01