NodeJS 如何在异步等待调用节点上设置超时

jslywgbw  于 2022-12-12  发布在  Node.js
关注(0)|答案(5)|浏览(268)

如何将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!
  }
};
zi8p0yeb

zi8p0yeb1#

您可以使用一个简单的小函数来返回一个在延迟后解决的承诺:

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

// or a more condensed version
const delay = (t, val) => new Promise(resolve => setTimeout(resolve, t, val));

然后,在循环中执行await

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

注意:我还将您的for循环切换为使用for/of,这不是必需的,但比您所拥有的要干净一些。
或者,在nodejs的现代版本中,可以使用timersPromises.setTimeout(),它是一个返回承诺的内置计时器(从nodejs v15开始):

const setTimeoutP = require('timers/promises').setTimeout;

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

oprakyz72#

实际上,我有一段非常标准的代码来实现这一点:

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

用法:

await PromiseTimeout(1000);

如果你使用的是蓝鸟承诺,那么它内置为Promise.timeout
更对你的问题:你看过API文档了吗?有些API会告诉你在下一次请求之前你需要等待多长时间。或者允许大量下载数据。

gr8qqesn

gr8qqesn3#

从节点v15开始,您可以使用计时器承诺API:

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

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

test();

请注意,此功能是实验性的,可能会在未来版本中变更。

wnavrhmk

wnavrhmk4#

从节点15及以上版本开始,有了新的Timers Promises API,您可以避免构建 Package :

import {
  setTimeout,
  setImmediate,
  setInterval,
} from 'timers/promises';

console.log('before')
await setTimeout(1000)
console.log('after 1 sec')

所以你的问题你可以用异步迭代器来写:

import {
  setTimeout
} from 'timers/promises'

async function getProducts (req, res) {
  const productids = [1, 2, 3]

  for await (const product of processData(productids)) {
    console.log(product)
  }
}

async function * processData (productids) {
  while (productids.length > 0) {
    const id = productids.pop()
    const product = { id }
    yield product
    await setTimeout(5000)
  }
}

getProducts()
vfh0ocws

vfh0ocws5#

我已经做了如下的API延迟测试。可以通过挂起setTimeout来延迟它。
第一个

相关问题