Комбинация асинхронной функции + 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 работает слишком быстро, и скрипт отправляет слишком много запросов в секунду в API google. Поэтому я хотел бы построить функцию сна, которая задерживает запрос. Таким образом я мог бы также использовать эту функцию для задержки другие запросы. Если есть другой способ отложить запрос, пожалуйста, дайте мне знать.

в любом случае, это мой новый код, который не работает. Ответ на запрос возвращается анонимной асинхронной функции в пределах setTimeout, но я просто не знаю, как я могу вернуть ответ на функцию сна resp. к начальной функции 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);
  }

Я уже пробовал некоторые варианты: сохранение ответа в глобальной переменной и возврат его из функции сна, обратный вызов в анонимной функции и т. д.

4 102

4 ответа:

код

Начиная С Узла 7.6, вы можете комбинировать функции promisify функция из модуля utils с setTimeout() .

узел.js

const sleep = require('util').promisify(setTimeout)

Javascript

const sleep = m => new Promise(r => setTimeout(r, m));

использование

async function main() {
    console.time("Slept for")
    await sleep(3000)
    console.timeEnd("Slept for")
}

main()

setTimeout - это не async функция, поэтому вы не можете использовать ее с ES7 async-await. Но вы могли бы реализовать свой sleep функция с помощью ES6 обещание:

function sleep (fn, par) {
  return new Promise((resolve) => {
    // wait 3s before calling fn(par)
    setTimeout(() => resolve(fn(par)), 3000)
  })
}

затем вы сможете использовать этот новый sleep функция с ES7 async-await:

var fileList = await sleep(listFiles, nextPageToken)

Пожалуйста, обратите внимание что я только отвечаю на ваш вопрос об объединении ES7 async/await с setTimeout, хотя это может не помочь решить вашу проблему с отправкой слишком много запросов в второй.

быстрый ОДН-вкладыш, встроенный путь

 await new Promise((resolve) => setTimeout(() => resolve(), 1000));