如何不忘记在Javascript中使用等待?

kdb*_*kdb 12 javascript asynchronous async-await

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

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

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

但是,现在我需要在await任何地方写,并且引入奇怪的错误就像if(DEBUG){...}总是被执行变得太容易了.

虽然似乎可以使用ESLINT识别错误,但await在任何地方写入看起来都是不必要的麻烦,因此我想知道Javascript是否有一些我错过的更好的构造?

(主观上我当前使用的await/async似乎是向后的;除非明确等待,否则Promise保持原样,但我似乎更希望在异步函数中默认等待承诺,并且仅在明确请求时保持为裸承诺.)

Ber*_*rgi 6

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

const debug = await debugPromise
Run Code Online (Sandbox Code Playgroud)

在那里你可以很快看到它if (debug)很好但if (debugPromise)不是.


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

我不会这样做.尽量使异步函数尽可能少.如果他们本身没有进行本质上异步的事情,而只依赖于某些承诺的结果,则将这些结果声明为函数的参数.一个简单的例子:

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

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

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

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

// 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(…) …
}());
Run Code Online (Sandbox Code Playgroud)