我正在使用node v10.15.3
,并且试图暂停4 seconds
进行api调用。
我尝试了以下操作:
let arr = ["Product 1", "Product 2", "Product 3", "Product 4"]
function callApi() {
console.log("start - " + new Date().toString());
for (var i = 0; i <= arr.length; i++) {
(function(index) {
setTimeout(async() => {
// here usually comes the api call
await console.log(arr[index]);
await console.log(new Date().toString());
}, 4000);
})(i);
}
console.log("end - " + new Date().toString());
}
callApi()
从输出中可以看到,首先输出消息start
和end
,然后运行for-loop
。但是,我想在每个函数运行4秒之间等待并获得以下输出:
start - Sun Sep 08 2019 13:28:03
Product 1
Sun Sep 08 2019 13:32:07
Product 2
Sun Sep 08 2019 13:36:07
Product 3
Sun Sep 08 2019 13:40:07
Product 4
Sun Sep 08 2019 13:44:07
end - Sun Sep 08 2019 13:28:03
任何建议我做错了。
答案 0 :(得分:2)
setTimeout(..., 4000)
-在循环的每次迭代中,您调用setTimeout
的功能均不同,但延迟相同,因此计划将这四个功能从现在起4秒同时运行。 / p>
相反,请尝试:setTimeout(..., 4000 * (index + 1))
。
或者,由于您已经在使用await
,因此可以通过将setTimeout
包装在Promise
中来更清楚地编写此代码:
let arr = ["Product 1", "Product 2", "Product 3", "Product 4"]
function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
async function callApi() {
console.log("start - " + new Date().toString());
for (let i = 0; i <= arr.length; i++) {
await sleep(4000);
console.log(arr[i]);
console.log(new Date().toString());
}
console.log("end - " + new Date().toString());
}
callApi()
旁注:await
与console.log
一起使用时无效,因为后者不会返回Promise
(也许您以前有与网络相关的代码,在这里确实使用了promise,这只是剩菜吗?)。
答案 1 :(得分:2)
仅在await
循环主体中使用for
可能更有意义:
let arr = ["Product 1", "Product 2", "Product 3", "Product 4"];
const delay = ms => new Promise(res => setTimeout(res, ms));
async function callApi() {
for (const item of arr) {
await delay(2000); // example API call
console.log(item);
}
}
callApi()
答案 2 :(得分:2)
async
函数是一个能够停止执行代码并能够await
解决异步任务(通常是一个承诺)的功能。由于您的for loop
位于外部函数(不是异步函数)中,因此它将无需等待任何内容即可完成循环,只需启动几个独立的setTimeout
。
要修复您的函数,请像下面这样重写它:
async function callApi() {
for (var i = 0; i <= arr.length; i++) {
// here usually comes the api call
await request(i)
}
}
function request(i) {
return new Promise((resolve) => {
setTimeout(() => {
console.log(i);
resolve();
}, 4000);
}
}
“暂停”功能背后的功能称为generators
,以备您了解其工作原理。