如何不忘记在Javascript中使用Wait everywhere?
我试图编写一个小小的chrome扩展,它依赖于如何不忘记在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.*
接口的大量回调查询函数,我很快就找到了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 aPromise.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(…) …
}());