将callback转换为Promise

我想转换下面的callEndPointWrapper返回一个Promise而不是callback。 我已经testing了下面的代码,但在等待Promise for callEndpointWrapper()请求超时。 我是否错过了下面的任何东西? (在debugging的时候,我看到请求超出了代码的下面,等待Promise: return (function callEndpoint(callback): any {

回电话:

  function callEndPointWrapper(): any { return function callEndpoint(callback) { try { // gRPC call client[methodName](req, options, callback); } catch (err) { callback(err); } }; } const result = yield callEndpointWrapper(); // I get the correct result from callback above (both on success or error) 

诺言:

 function callEndPointWrapper(): Promise<any> { return new Promise( (resolve, reject) => { return (function callEndpoint(callback): any { try { // gRPC call resolve(client[methodName](req, options, callback)); } catch (err) { reject(callback(err)); } }); }); const result = await callEndpointWrapper(); // Above request times out. 

callEndPointWrapper的所需结果似乎是一个函数( callEndPoint ),它执行一些asynchronous工作,您可以进一步调用它来执行某些操作。

在您的callback方法中,您正在生成此callEndPoint函数。

—-> callEndPointWrapper返回asynchronous工作的callEndPoint

另一方面,在您的基于承诺的方法中,您正尝试产生callEndPoint的结果,而不是返回callEndPoint本身。 事实上,在Promise构造函数中从不调用callEndPoint

—-> callEndPointWrapper返回一个承诺,永远不会解决,并在内部创buildcallEndPoint函数什么都不做,因为它永远不会被调用。

请注意,一次调用callEndPointWrapper不是asynchronous的。 实际的asynchronous部分(假设client方法是asynchronous的)发生在callEndpoint所以对于基于callback的方法的asynchronous调用将是这样的:

 callEndPointWrapper()( function callback(responseFromEndpoint) { // ... } ) // or something like let caller = callEndPointWrapper(); caller(function callback(responseFromEndpoint) { // ... }); 

由此可见,基于承诺的方法还需要两个调用:

 await callEndPointWrapper()(); // call a wrapper which returns a function which returns a promise 

您的callback代码的基于承诺的代码在function上等效(根据生成的结果)如下:

 function callEndPointWrapper(): any { return function callEndpoint() { return new Promise((resolve, reject) => { try { client[methodName](req, options, (err, result) => { if (err) return reject(err); resolve(result); }); } catch (err) { // Note: this rejection will only happen on any sync errors // with the above code, such as trying to invoke a non-existing // method on the client. This type of error is a programmer error // rather than an operational error in the system so you should // consider if such errors should even by caught by your code. reject(err); } }); }; } 

然而,如果你没有在callEndpoint函数的闭包中传递任何configuration选项,这会导致如何使用包装函数?

根据您的示例使用情况,您所需要的只是callEndpoint方法。


想到你可能会使用类似co东西,它允许你yield函数(thunk),并在内部用callback调用它们。

所以,当你这样做

 yield callEndpointWrapper() 

你实际上正在打电话

 yield function callEndpoint(callback) { // ... } 

然后co为你做了一些魔术。

这是一个被co弃用的模式,总体上不适合使用。 更不用说,这是非常混乱(和丑陋的恕我直言)的行为,需要知识的特定图书馆。

要使用co promise,你不需要包装函数。 只是yieldawait调用callEndPoint (与我上面的诺言中的例子相同)的结果,这将是一个承诺。

 yield callEndPoint() // or await callEndPoint()