web-dev-qa-db-ja.com

複数のリクエストが連続して実行されるように、http.request()の結果を待機して返す方法は?

関数doRequest(options)があるとします。これはHTTPリクエストを実行することになっており、そのためにhttp.request()を使用します。

doRequest()がループ内で呼び出される場合、次の要求が前の完了(シリアル実行、次々に)の後に行われるようにします。コールバックとPromiseを混乱させないために、async/awaitパターンを使用します(Node 6+)で実行するBabel.jsでコンパイルされます)。

ただし、応答オブジェクトがさらに処理されるのを待つ方法と、doRequest()の結果としてそれを返す方法は、私には不明です。

_var doRequest = async function (options) {

    var req = await http.request(options);

    // do we need "await" here somehow?
    req.on('response', res => {
        console.log('response received');
        return res.statusCode;
    });
    req.end(); // make the request, returns just a boolean

    // return some result here?!
};
_

HTTPリクエストにさまざまなオプションを使用してmochaを使用して現在のコードを実行すると、すべてのリクエストが同時に行われるようです。おそらくdoRequest()が実際には何も返さないため、これらはすべて失敗します。

_describe('Requests', function() {
    var t = [ /* request options */ ];
    t.forEach(function(options) {
        it('should return 200: ' + options.path, () => {
            chai.assert.equal(doRequest(options), 200);
        });
    });
});
_
12
CoDEmanX

async/await promiseで動作します。 async関数であるawaitingがPromiseを返す場合にのみ機能します。

問題を解決するには、request-promiseなどのライブラリを使用するか、doRequest関数からプロミスを返すことができます。

後者を使用したソリューションを次に示します。

function doRequest(options) {
  return new Promise ((resolve, reject) => {
    let req = http.request(options);

    req.on('response', res => {
      resolve(res);
    });

    req.on('error', err => {
      reject(err);
    });
  }); 
}

describe('Requests', function() {
  var t = [ /* request options */ ];
  t.forEach(function(options) {
    it('should return 200: ' + options.path, async function () {
      try {
        let res = await doRequest(options);
        chai.assert.equal(res.statusCode, 200);
      } catch (err) {
        console.log('some error occurred...');
      }
    });
  });
});
24
mkhanoyan

it関数にdoneを渡すことができるはずです。次に、非同期の要求が完了したら、アサートの後にdone()行を追加します。エラーがある場合は、done(myError)のように完了関数に渡します

https://mochajs.org/#asynchronous-code 詳細情報

0
LostJon