【发布时间】:2020-11-09 02:03:23
【问题描述】:
假设我有这个函数doSomeThing(),它有条件地在工作线程(异步)中运行一些非常昂贵的代码,但大多数时候它需要运行同步。
有什么方法可以同步使用这个异步函数吗?我认为没有。
那么除了创建两个几乎相同的函数之外,我还有什么其他选择,它们的区别仅在于同步与异步方法?是否有一些我忽略的 DRYer 替代方案?
async function doSomeThing(input, shouldDoExpensiveStuff) {
let output = parseInt(input)
// ... A lot of shared logic
if (shouldDoExpensiveStuff) {
output = await offloadToWorker(input);
} else {
output += 1;
}
// ... A lot of other shared logic
return output;
}
我知道我可以将很多共享逻辑转移到新的 doSomeThingSync 和 doSomeThingAsync 可以共享的单个函数中,但它确实看起来非常不理想且乏味,我可能需要使用数字来执行此操作功能。
我控制 JS 执行环境,所以浏览器兼容性不是问题。通过 Babel 进行的任何花哨的 ECMA 魔法都是公平的游戏。
【问题讨论】:
-
同步运行是否有特定原因?我的意思是:当你执行异步函数时,它不需要做昂贵的事情,它几乎和同步函数一样快,调用这个函数的函数并不关心,因为它期望返回一个承诺无论如何,它只会按照这个承诺行事。我认为这是非常干净的代码。
-
好问题。原因是第三方库是调用者,而调用者不是
async function。因此,调用返回 promise 的函数的结果会导致存储的值成为待处理的 promise,而不是预期的结果。 -
听起来你已经想通了。将所有共享逻辑移至共享函数。
-
但是第三方不应该知道它调用的函数的签名吗?当您实施您的建议(2 个函数,一个异步一个不)时,第三方也应该知道要调用哪一个。如果第三方函数需要同步结果,则您不能在函数中运行异步工作器并使用该结果。
-
@Slbox 听起来你确实有两个独立的函数,它们做不同的事情并在不同的地方调用(一个做昂贵的事情,另一个不做)。您能否发布您正在处理的具体代码?共享代码究竟做了什么,它如何与
input和output交互?为什么你有这么多遵循这种模式的功能,它们都做同样的事情吗?
标签: javascript ecmascript-6 async-await es6-promise ecmascript-next