简体   繁体   English

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

[英]How to return synchronous result to asynchronous function call

In Node 13, an external 3rd party library calls my code:在 Node 13 中,外部 3rd 方库调用我的代码:

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

As my code then has to perform nested synchronous calls, how could I provide an appropriate return value to the 3rd party library that is not a promise, but the result of my promises?由于我的代码必须执行嵌套的同步调用,我如何向第 3 方库提供适当的返回值,该返回值不是承诺,而是我的承诺的结果? Ideally something like this:理想情况下是这样的:

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 would be a good solution, except it has an unresolved bug that causes nested promises to not resolve. deasync将是一个很好的解决方案,除非它有一个未解决的错误,导致嵌套的 promise 无法解决。

Well, there is no way to synchronously return (from the callback) a value that you obtain asynchronously within the callback.好吧,没有办法同步返回(从回调)您在回调中异步获取的值。 Javascript does not currently support that. Javascript 目前不支持。 So, these are your options:所以,这些是你的选择:

  1. Put the asynchronous code in a child_process.将异步代码放在 child_process 中。 Then run that child process with something like child_process.execFileSync() .然后使用child_process.execFileSync()类的东西运行该子进程。 That allows you to run the asynchronous code in the child process, but have the parent process block and wait for the result.这允许您在子进程中运行异步代码,但让父进程阻塞并等待结果。 This is a hack because it blocks the parent while waiting for the result.这是一个黑客,因为它在等待结果时阻止了父级。 But, it can be made to work.但是,它可以工作。

  2. Before calling the library function, prefetch whatever value it is you will need when the callback is called.在调用库函数之前,预取调用回调时所需的任何值。 This allows you to use regular asynchronous programming before you call the library and then once you have the desired value in some sort of cache, you can then call the 3rd party library and when it calls you back and wants the value, you will have it synchronously in a cache somewhere.这允许您在调用库之前使用常规异步编程,然后一旦您在某种缓存中拥有所需的值,您就可以调用第 3 方库,当它回叫您并想要该值时,您将拥有它在某处的缓存中同步。 Obviously, this only works if you can figure what value or range of possible values will be required in the callback so you can pre-fetch them.显然,这只有在您可以确定回调中需要什么值或可能值的范围时才有效,以便您可以预取它们。

  3. Modify the code in the library to add support for an asycnhronous callback.修改库中的代码以添加对异步回调的支持。

  4. Redesign code to work a different way that doesn't require this library or that can use some other library that doesn't have this problem.重新设计代码以采用不需要此库或可以使用其他没有此问题的库的不同方式工作。

  5. Write or find some native code add-on (like deasync ) that lets you block somehow during the asynchronous operation while still letting the event queue do what it needs to do to process the asynchronous completion.编写或找到一些本机代码插件(如deasync ),让您在异步操作期间以某种方式阻塞,同时仍然让事件队列执行处理异步完成所需的操作。 This would have to hook deep into the internals of the V8 engine.这将不得不深入了解 V8 引擎的内部结构。 Or fix, deasync so it works for your case.或者修复, deasync以便它适用于您的情况。

  6. Write a blocking add-on in native code that could carry out your asynchronous operation in native code while blocking the V8 engine.用本机代码编写一个阻塞插件,它可以在阻塞 V8 引擎的同时用本机代码执行异步操作。

FYI, since everything but #2, #3 and #4 all block the main JS thread which is generally a bad thing to do in any server environment, and you've said that #2 was not practical, my preference would be #3 or #4.仅供参考,因为除 #2、#3 和 #4 之外的所有内容都阻塞了主 JS 线程,这在任何服务器环境中通常都是一件坏事,而且您已经说过 #2 不实用,我的偏好是 #3或#4。 Since you don't share the actual code and actual detailed library and problem, we can't help you with any specifics.由于您没有分享实际代码和实际详细的库和问题,我们无法为您提供任何细节。

Probably the most straightforward solution to implement is #1 (package the code up into a child process that you run synchronously), but it blocks the app while running which is a downside.可能最直接的解决方案是#1(将代码打包到一个同步运行的子进程中),但它在运行时阻塞了应用程序,这是一个缺点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM