非同期関数 + await + setTimeout の組み合わせ 質問する

非同期関数 + await + setTimeout の組み合わせ 質問する

私は新しい非同期機能を使用しようとしており、私の問題を解決することで将来他の人の役に立つことを願っています。これは動作している私のコードです:

  async function asyncGenerator() {
    // other code
    while (goOn) {
      // other code
      var fileList = await listFiles(nextPageToken);
      var parents = await requestParents(fileList);
      // other code
    }
    // other code
  }

  function listFiles(token) {
    return gapi.client.drive.files.list({
      'maxResults': sizeResults,
      'pageToken': token,
      'q': query
    });
  }

問題は、whileループの実行速度が速すぎて、スクリプトが Google API に 1 秒あたりに送信するリクエストが多すぎることです。そのため、リクエストを遅延させるスリープ関数を構築したいと思います。この関数を使用して、他のリクエストを遅延させることもできます。リクエストを遅延させる別の方法がある場合は、お知らせください。

とにかく、これは動作しない私の新しいコードです。リクエストの応答は setTimeout 内の匿名の非同期関数に返されますが、応答を sleep 関数または初期の asyncGenerator 関数に返す方法がわかりません。

  async function asyncGenerator() {
    // other code
    while (goOn) {
      // other code
      var fileList = await sleep(listFiles, nextPageToken);
      var parents = await requestParents(fileList);
      // other code
    }
    // other code
  }

  function listFiles(token) {
    return gapi.client.drive.files.list({
      'maxResults': sizeResults,
      'pageToken': token,
      'q': query
    });
  }

  async function sleep(fn, par) {
    return await setTimeout(async function() {
      await fn(par);
    }, 3000, fn, par);
  }

すでにいくつかのオプションを試しました: 応答をグローバル変数に保存してスリープ関数から返す、匿名関数内でコールバックするなど。

ベストアンサー1

関数sleepが動作しないのは、setTimeout(まだ?) ed 可能な promise を返さないためですawait。手動で promise 化する必要があります。

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleep(fn, ...args) {
    await timeout(3000);
    return fn(...args);
}

sleepちなみに、ループを遅くするために、コールバックを受け取ってこれを延期する関数はおそらく使用したくないでしょう。私は以下をお勧めします:

while (goOn) {
  // other code
  var [parents] = await Promise.all([
      listFiles(nextPageToken).then(requestParents),
      timeout(5000)
  ]);
  // other code
}

これにより、計算にはparents少なくとも 5 秒かかります。

おすすめ記事