node.js 使用 setInterval 异步等待
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52184291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
async await with setInterval
提问by Andrey Radkevich
function first(){
console.log('first')
}
function second(){
console.log('second')
}
let interval = async ()=>{
await setInterval(first,2000)
await setInterval(second,2000)
}
interval();
Imagine that I have this code above.
想象一下,我上面有这段代码。
When I run it, first()and second()will be called at the same time; how do I call second()after first)()returns some data, for example, if first()is done, only then call second()?
当我运行它,first()并second()会在同一时间被调用; 返回一些数据second()后如何调用first)(),例如,如果first()完成,然后才调用second()?
Because first()in my code will be working with a big amount of data and if this 2 functions will be calling at the same time, it will be hard for the server.
因为first()在我的代码中将处理大量数据,如果这两个函数将同时调用,服务器将很难。
How do I call second()each time when first()will return some data?
second()每次first()返回一些数据时如何调用?
回答by Madara's Ghost
You have a few problems:
你有几个问题:
- Promises may only ever resolve once,
setInterval()is meant to call the callback multiple times, Promises do not support this case well. - Neither
setInterval(), nor the more appropriatesetTimeout()return Promises, therefore,awaiting on them is pointless in this context.
- Promises 可能只解析一次,
setInterval()意味着多次调用回调,Promises 不能很好地支持这种情况。 - 无论是
setInterval(),还是比较合适setTimeout()的回报的承诺,因此,await荷兰国际集团对他们在这方面毫无意义。
You're looking for a function that returns a Promise which resolves after some times (using setTimeout(), probably, not setInterval()).
您正在寻找一个返回 Promise 的函数,该函数在一段时间后解析(使用setTimeout(),可能,不是setInterval())。
Luckily, creating such a function is rather trivial:
幸运的是,创建这样一个函数相当简单:
async function delay(ms) {
// return await for better async stack trace support in case of errors.
return await new Promise(resolve => setTimeout(resolve, ms));
}
With this new delayfunction, you can implement your desired flow:
使用这个新delay功能,您可以实现您想要的流程:
function first(){
console.log('first')
}
function second(){
console.log('second')
}
let run = async ()=>{
await delay(2000);
first();
await delay(2000)
second();
}
run();
回答by mdikici
As mentioned above setIntervaldoes not play well with promises if you do not stop it. In case you clear the interval you can use it like:
如上所述,如果你不阻止它,那么setIntervalPromise 就不会很好地发挥作用。如果您清除了间隔,您可以像这样使用它:
async function waitUntil(condition) {
return await new Promise(resolve => {
const interval = setInterval(() => {
if (condition) {
resolve('foo');
clearInterval(interval);
};
}, 1000);
});
}
Later you can use it like
以后你可以像这样使用它
const bar = waitUntil(someConditionHere)
回答by Estus Flask
setIntervaldoesn't play well with promises because it triggers a callback multiple times, while promise resolves once.
setInterval不适合使用 promise,因为它会多次触发回调,而 promise 会解析一次。
It seems that it's setTimeoutthat fits the case. It should be promisified in order to be used with async..await:
似乎它很setTimeout适合这种情况。它应该被promisified以便与async..await:
async () => {
await new Promise(resolve => setTimeout(() => resolve(first()), 2000));
await new Promise(resolve => setTimeout(() => resolve(second()), 2000));
}
回答by Guanhua Xin
await expression causes async to pause until a Promise is settled
await 表达式导致 async 暂停,直到 Promise 被解决
so you can directly get the promise's result without await
所以你可以直接得到promise的结果而无需等待
for me, I want to initiate Http request every 1s
对我来说,我想每 1 秒发起一次 Http 请求
let intervalid
async function testFunction() {
intervalid = setInterval(() => {
// I use axios like: axios.get('/user?ID=12345').then
new Promise(function(resolve, reject){
resolve('something')
}).then(res => {
if (condition) {
// do something
} else {
clearInterval(intervalid)
}
})
}, 1000)
}
// you can use this function like
testFunction()
// or stop the setInterval in any place by
clearInterval(intervalid)

![node.js 如何修复此错误 TypeError [ERR_INVALID_CALLBACK]: Callback must be a function](/res/img/loading.gif)