如何不忘记在Javascript中使用Wait everywhere?

如何不忘记在Javascript中使用Wait everywhere?,javascript,asynchronous,async-await,Javascript,Asynchronous,Async Await,我试图编写一个小小的chrome扩展,它依赖于chrome.*接口的大量回调查询函数,我很快就找到了promises和async/await,因为我需要保证某些操作的顺序,同时试图避免 然而,一旦我在一些函数中引入了async/await,使用它们的每个函数也必须转换为async函数,以便能够await返回值。最终,甚至一些全局常数也变成了承诺,例如 const DEBUG = new Promise(function(resolve){ chrome.management.getSel

我试图编写一个小小的chrome扩展,它依赖于
chrome.*
接口的大量回调查询函数,我很快就找到了promises和async/await,因为我需要保证某些操作的顺序,同时试图避免

然而,一旦我在一些函数中引入了async/await,使用它们的每个函数也必须转换为
async函数
,以便能够
await
返回值。最终,甚至一些全局常数也变成了承诺,例如

const DEBUG = new Promise(function(resolve){
    chrome.management.getSelf(resolve);
}).then(function(self){
    return self.installType == 'development';
});
然而,现在我需要在任何地方编写
wait
,并且引入像
if(DEBUG){…}
这样的奇怪的bug总是被执行变得太容易了

虽然似乎,在任何地方编写
wait
都是不必要的麻烦,因此我想知道Javascript是否有我所缺少的更好的结构?


(主观上,我目前对wait/async的使用似乎有些倒退;除非明确等待,否则承诺会保持原样,但我更希望在异步函数中默认等待承诺,并且只有在明确请求时才保持原样。)

因为缺少一个可以轻松捕捉此类错误的类型系统(您是否考虑过类型化或流?),您可以使用变量名。选择后缀的前缀,如<代码> P<代码> > <代码>承诺> />代码>或<代码> $>代码>,并将其添加到所有的承诺变量中,类似于异步函数通常如何命名为<代码>异步后缀。然后只做“< /p>”之类的事情。
const debug = await debugPromise
您可以快速看到
if(debug)
很好,但是
if(debugPromise)
不好


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

我不会这么做。尽量减少函数的异步性。如果它们本身不做本质上异步的事情,而只依赖于某些承诺的结果,则将这些结果声明为函数的参数。一个简单的示例:

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

同样的模式也可以应用于全局函数-要么将其作为每个函数的显式参数,要么将其作为包含所有其他函数的模块函数的参数作为闭包。然后
在声明或执行任何其他操作之前,在模块中只等待一次全局承诺,然后使用普通结果值

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


不确定这是否是您正在寻找的,但您始终可以链接您的语句,即
newpromise(…)。然后(…)。然后(…)
关于全局常量,只需将整个模块包装在一个函数中,该函数
await
s a
Promise.all
包含所有异步加载的常量,然后才执行主脚本。“一旦引入异步/await”-我很确定您以前遇到过完全相同的问题,因为您的逻辑始终是异步的。无论您是使用回调、承诺还是带有
await
sugar的承诺。@Patrickbar这本质上是一种不同的语法,具有相同的问题。只是现在不再使用
const x=await getX();const y=await x.getY();dostuff(x,y);…
我会写
getX()。然后(x=>Promise.all([x,x.getY()])。然后([x,y])=>{dostuff(x,y);…})
,这并不难忘记,但如果忘记了,重构起来就难多了。。参见“陷阱3”(扰流板:你可以将异步函数的结果视为承诺)关于命名,一个
Async
后缀非常常见;这是一个,但也是一个。@stephenleary谢谢,我已经在想是否应该澄清,承诺变量和异步函数不会使用相同的后缀。谢谢你,Bergi。解释得很清楚。这很好。还有两种情况-1)异步/等待使用承诺期间出错。2) 使用异步/等待承诺时拒绝使用问题。如何遵循处理异步/等待错误的良好实践?第二,在执行异步/等待承诺时,有没有处理拒绝代码的好方法?任何引用或代码示例都是fine@Gary只需像其他地方一样使用
尝试
/
捕获
。或者取决于你到底需要什么。@FrankNocke“可以被视为“几乎没有意义”。它们是承诺:-)
// 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(…) …
}());