web-dev-qa-db-ja.com

非同期待機呼び出しノードでタイムアウトを設定する方法

非同期のawait関数呼び出しにsetTimeoutを追加するにはどうすればよいですか?

私が持っています

    request = await getProduct(productids[i]);

どこ

const getProduct = async productid => {
        return requestPromise(url + productid);
   };

私はもう試した

    request = await setTimeout((getProduct(productids[i])), 5000);

エラーが発生しましたTypeError: "callback" argument must be a function理にかなっています。リクエストがループの内側にあるため、API呼び出しのレート制限に達します。

exports.getProducts = async (req, res) => {
  let request;
  for (let i = 0; i <= productids.length - 1; i++) {
    request = await getProduct(productids[i]);
    //I want to wait 5 seconds before making another call in this loop!
  }
};
5
jenryb

遅延後に解決するpromiseを返す単純な小さな関数を使用できます。

function delay(t, val) {
   return new Promise(function(resolve) {
       setTimeout(function() {
           resolve(val);
       }, t);
   });
}

そして、ループ内のawaitです。

exports.getProducts = async (req, res) => {
  let request;
  for (let id of productids) {
    request = await getProduct(id);
    await delay(5000);
  }
};

注:forループを切り替えてfor/ofを使用するように変更しましたが、これは必須ではありませんが、以前のものより少しクリーンです。

7
jfriend00

実際、私はそれを行うために使用するかなり標準的なコードの塊を持っています:

function PromiseTimeout(delayms) {
    return new Promise(function (resolve, reject) {
        setTimeout(resolve, delayms);
    });
}

使用法:

await PromiseTimeout(1000);

Bluebird promiseを使用している場合、それは Promise.timeout として組み込まれています。

問題の詳細:APIドキュメントを確認しましたか?一部のAPIは、次のリクエストまでに待機する必要がある量を通知します。または、大量のデータのダウンロードを許可します。

2
Giulio Bambini