【问题标题】:How to return synchronous result to asynchronous function call如何将同步结果返回给异步函数调用
【发布时间】:2019-11-25 16:41:12
【问题描述】:

在节点 13 中,外部 3rd 方库调用我的代码:

const myInput = myCode.run(somVar); // it doesn't use await

由于我的代码必须执行嵌套的同步调用,我如何向 3rd 方库提供一个适当的返回值,它不是一个承诺,而是我的承诺的结果?理想情况下是这样的:

const run = (inputVar) =>{
   let result
   (async ()=>{  
      result = await doSyncCalls(inputVar);
   })(); // code should not proceed until after await
   return result;
} // will return undefined, but ideally should return doSyncCalls result

deasync 将是一个很好的解决方案,但它有一个未解决的错误导致嵌套的 Promise 无法解决。

【问题讨论】:

  • 你做不到。根据定义,异步函数在结果确定之前立即返回。
  • 那是因为你不能做你想做的事。从异步函数返回值是不可能的。
  • 正如您在问题中指出的那样,它并不能完全发挥作用。
  • 我重新打开了这个问题,所以它不会被忽略。但如果有人确实有解决方案,则应将其添加到链接问题中,因为这是大多数搜索的最终结果。
  • 好吧,如果你愿意在这个异步操作期间阻塞你的整个 node.js 进程(这基本上是你要求做的),那么你可以使用同步 child_process 函数,例如execFileSync() 同步运行另一个应用程序来执行你的异步操作,获取结果并返回它。我之前似乎提出了将异步操作转换为同步操作的唯一方法,但我从未见过它实际上是一个好的设计选择。

标签: javascript node.js promise


【解决方案1】:

嗯,没有办法同步返回(从回调中)一个您在回调中异步获得的值。 Javascript 目前不支持。所以,这些是你的选择:

  1. 将异步代码放在 child_process 中。然后使用child_process.execFileSync() 之类的内容运行该子进程。这允许您在子进程中运行异步代码,但让父进程阻塞并等待结果。这是一个 hack,因为它在等待结果时阻止了父级。但是,它可以工作。

  2. 在调用库函数之前,预取调用回调时所需的任何值。这允许您在调用库之前使用常规异步编程,然后一旦您在某种缓存中获得所需的值,您就可以调用第 3 方库,当它回叫您并想要该值时,您将拥有它在某处的缓存中同步。显然,只有在您能够确定回调中需要什么值或可能值的范围以便您可以预取它们时,这才有效。

  3. 修改库中的代码以添加对异步回调的支持。

  4. 重新设计代码以采用不同的方式工作,不需要此库或可以使用不存在此问题的其他库。

  5. 编写或查找一些本机代码插件(如deasync),让您在异步操作期间以某种方式阻塞,同时仍让事件队列执行处理异步完成所需的操作。这必须深入到 V8 引擎的内部。或者修复,deasync,使其适用于您的情况。

  6. 在本机代码中编写一个阻塞插件,可以在本机代码中执行异步操作,同时阻塞 V8 引擎。

仅供参考,因为除了 #2、#3 和 #4 之外的所有内容都阻塞了主 JS 线程,这在任何服务器环境中通常都是一件坏事,而且你说过 #2 不实用,我的偏好是是#3或#4。由于您不分享实际代码和实际详细的库和问题,我们无法帮助您提供任何细节。

可能最直接的解决方案是#1(将代码打包到您同步运行的子进程中),但它会在运行时阻塞应用程序,这是一个缺点。

【讨论】:

  • 谢谢 jfriend00 - 这些都是很好的建议。我仍在为此苦苦挣扎,一旦我证明了您的建议之一或其他内容,我就会回复。
猜你喜欢
  • 2019-09-30
  • 1970-01-01
  • 2020-03-15
  • 2022-12-22
  • 2013-07-19
  • 2023-04-01
  • 2010-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多