如何将同步结果返回给异步函数调用

时间:2019-11-23 08:15:35

标签: javascript node.js promise

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

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

由于我的代码随后必须执行嵌套的同步调用,因此我如何向第三方库(不是诺言,而是诺言的结果)提供适当的返回值?理想情况是这样的:

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无法解决。

1 个答案:

答案 0 :(得分:1)

那么,没有办法从回调中同步返回(从回调)您异步获取的值。 Javascript目前不支持。因此,这些是您的选择:

  1. 将异步代码放入child_process中。然后使用类似child_process.execFileSync()的命令运行该子进程。这样,您就可以在子进程中运行异步代码,但可以使父进程处于阻塞状态并等待结果。这是一种黑客,因为它在等待结果时阻止了父级。但是,可以使其正常工作。

  2. 在调用库函数之前,预取调用回调时所需的任何值。这样,您可以在调用库之前使用常规的异步编程,然后在某种类型的缓存中拥有所需的值之后,便可以调用第三方库,当它返回并想要该值时,您将拥有它。在某处的缓存中同步。显然,这仅在您可以确定回调中需要什么值或可能值的范围以便可以预取它们时才有效。

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

  4. 重新设计代码,以一种不需要该库的方式工作,或者可以使用其他没有此问题的库。

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

  6. 用本机代码编写一个阻止加载项,可以在阻止V8引擎的同时以本机代码执行异步操作。

仅供参考,由于#2,#3和#4之外的所有内容都阻塞了JS主线程,这在任何服务器环境中通常都是不好的事情,并且您已经说过#2不切实际,因此我倾向于是#3或#4。由于您没有共享实际的代码以及实际的详细库和问题,因此我们无法为您提供任何具体信息。

可能最容易实现的解决方案是#1(将代码打包成一个您可以同步运行的子进程),但是它在运行时阻止了应用程序,这是一个缺点。