如何在异步上setTimeout等待调用节点

时间:2018-04-29 22:20:39

标签: node.js callback async-await settimeout

如何在我的async 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!
  }
};

3 个答案:

答案 0 :(得分:8)

您可以使用一个简单的小函数来返回延迟后解析的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,这不是必需的,但比您所拥有的更清晰。

答案 1 :(得分:2)

实际上,我有一个非常标准的代码块,我用它来做:

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

用法:

await PromiseTimeout(1000);

如果您正在使用Bluebird承诺,那么它内置为Promise.timeout

更多问题:您是否检查过API文档?有些API会告诉您在下次请求之前需要等待多少。或者允许以更大的批量下载数据。

答案 2 :(得分:0)

从节点v15开始,您可以使用Timers Promises API

const timersPromises = require('timers/promises');

async function test() {
  await timersPromises.setTimeout(1000);
}

test();

请注意,此功能是试验性的,将来可能会更改。