更新的节点js具有async等待,这真的很酷,因为它使代码看起来更好。
我想知道让每个类方法都异步是个好主意,即使它不需要返回promise?
在我的用例中,我实际上有点需要,因为我试图在多个子进程之间共享依赖关系,并且我使用了代理和子进程通信的组合来实现这一点。显然,我需要承诺,因为我需要等待流程响应或发送消息。
但这可能会带来长期的潜在副作用吗?
更清楚地说,我仅是为了使用酷语法。
const database = CreateProxy('database');
await database.something();
来自另一个进程。
与某些仅向父进程请求something
的代码(例如
process.send('getSomethingFromDb');
内部都使用消息传递,但是第一个使它看起来好像不在表面上
答案 0 :(得分:5)
这个概念是Occam's razor的主题。没有好处,有缺点。
额外的开销(CPU和时间)是问题之一。承诺需要一些时间和资源来解决。这可能会花费不到一毫秒的时间,但滞后可能会累积。
另一个问题是,异步性具有传染性,一旦到达模块范围,async
IIFE应该在所有地方使用-因为尚不支持top-level await
:
module.export = (async () => {
await require('foo');
// await was accidentally dropped
// this results in race condition and incorrect error handling
require('foo');
...
})();
下面是一个使错误处理复杂化的缺点的好例子:
async function foo() {
throw new Error('foo');
}
async function bar() {
try {
return foo();
} catch (err) {
console.log('caught with bar');
}
}
bar(); // UnhandledPromiseRejectionWarning: Error: foo
尽管控制流在async
中看起来像同步的,但错误的处理方式却有所不同。 foo
返回拒绝的承诺,并且try..catch
函数中的async
不处理返回的值。拒绝不会在bar
中处理。
使用常规函数不会发生这种情况:
function foo() {
throw new Error('foo');
}
function bar() {
try {
return foo();
} catch (err) {
console.log('caught with bar');
}
}
bar(); // caught with bar
使用旨在同步工作的第三方库,事情可能会变得更加复杂。
答案 1 :(得分:2)
调用async
函数的结果将始终是Promise
,无论该函数是否实现任何异步行为。
const asyncTest = async () => 3;
console.log(asyncTest()); // logs 'Promise {<resolved>: 3}'
因此,您必须始终确保使用await
调用该函数。但这纯粹是一个舒适的问题,即使对您来说也是如此。而且,创建和解决Promises会增加每个函数调用的时间,因此,如果性能至关重要,则应避免大量调用async
函数,如果可以避免的话。
答案 2 :(得分:1)
我想知道让每个类方法异步是一个好主意, 即使不需要兑现承诺?
您的代码可以使用,但是由于两个原因,我不会推荐它:
不必要的内存/ CPU使用量
这将使您的代码难以理解。了解哪个功能是异步或同步的,对于理解系统的工作方式和功能很重要。