2017-11-10 6 views
1

コールバックの代わりにPromiseを返すように、以下のcallEndPointWrapperを変換します。 私は以下のコードでテストしましたが、callEndpointWrapper()のPromiseを待っている間に要求がタイムアウトしています。 私は以下を欠いていますか? プロミスため待つ間(デバッグ中私は上のコードの行の下に要求時間を参照してください return (function callEndpoint(callback): any {コールバックをPromiseに変換する

コールバック:

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. 
+0

このコードの動作はちょっと混乱します。コールバックベースのコードは、コールバックを受け付ける関数を返しますが、実際には非同期の仕事をしている関数です... 'await callEndpointWrapper()()' ...(2回の呼び出しに注意してください) ? 'callEndpoint'関数の終了時に利用可能な設定オプションを渡していなければ、ラッパー関数を持つことは何のポイントですか? – nem035

+0

@ nem035返信いただきありがとうございます。返信いただきありがとうございます.1回限りの呼び出し、すなわち 'await callEndPointWrapper()'であり、 'callEndpointWrapper'を呼び出す前に要求(req)とオプションがグローバル変数として設定されています。 – user2608576

+0

['co'](https://github.com/tj/co)を使用していますか? – nem035

答えて

1

callEndPointWrapperの望ましい結果はそうさらに何かを実行するために呼び出すことができる非同期作業を行う関数(callEndPoint)になります。

コールバックアプローチでは、このcallEndPoint関数を生成しています。

---->callEndPointWrapperは、非同期処理を行うcallEndPointを返します。

一方、約束ベースのアプローチでは、callEndPointを返すのではなく、callEndPointという結果を生成しようとしています。実際には、callEndPointPromiseコンストラクタ内で呼び出されることはありません。

---->callEndPointWrapperは決して解決されず、呼び出されないため何もしないcallEndPoint関数を内部的に作成する約束を返します。

callEndPointWrapperへの1回の呼び出しが非同期ではないことに注意することが重要です。実際の非同期部分(client方法を想定しては、非同期されている)callEndpointに起こるので、あなたのコールバックベースのアプローチのための非同期呼び出しは次のようなものになるだろう。このことから

callEndPointWrapper()(
    function callback(responseFromEndpoint) { 
    // ... 
    } 
) 

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

アプローチをベース約定が同様に2回の呼び出しを必要とすることになります:

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); 
     } 
     }); 
    }; 
} 
0:

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

Aは、コールバックコードの約束ベースのコード(生成された結果の点で)機能的に同等以下であります

しかし、callEndpoint関数のクロージャで利用可能な設定オプションを渡さないと、ラッパー関数を持つ点は何であるのでしょうか?

あなたの使用例に基づいて、必要なのはcallEndpointメソッドです。


それはあなたがyield機能(サンク)することができますし、コールバックと内部それらを呼び出すcoのようなものを使用している場合がありますことを気にしています。

あなたは

yield callEndpointWrapper() 

を行うときに、あなたが実際に

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

を呼び出しそしてcoさはあなたのためにボンネットの下にいくつかの魔法を行います。

これは、パターンがdeprecated by coであり、全体的に使用することをお勧めしません。それは非常に混乱している(と醜いIMHO)その特定のライブラリの知識を必要とする動作です。

約束をcoとするには、ラッパー機能は必要ありません。ちょうどyieldまたはawaitcallEndPoint(上記の私の約束の例と同じもの)を呼び出した結果、これは約束です。

yield callEndPoint() 
// or 
await callEndPoint() 
関連する問題