【问题标题】:Async / Await not actually waiting in while loopAsync / Await 实际上并未在 while 循环中等待
【发布时间】:2021-03-30 23:35:24
【问题描述】:
在我的项目即将结束时,我意识到对于它的最后一个组件,我别无选择,只能使用 Async、Await 和 Promise,以便程序等待 API 调用完成然后继续。尽管我了解到 Javascript 中确实没有“停止”或“等待”。我已经尝试了下面的代码,它在没有 while 循环的情况下工作,但有了它,它就停止工作了。我希望程序多次发送推文 API 调用,但我觉得 sendOff() 函数实际上并没有等待,并且循环只是跳过它,因为它运行得太快并且没有等待 API 调用完成。非常感谢任何帮助或攻击此问题的不同方法。
function sendTweets() {
return new Promise ((resolve, reject) => {
client.post('statuses/update', final_tweet, function(error, tweet, response) {
if (error) {
reject(error);
}
resolve(response);
});
});
}
async function sendOff() {
await sendTweets();
}
while (1) {
var final_tweet = { // Create tweet struct
status: "Hi!"
}
sendOff();
sleep.sleep(4);
}
编辑:对于那些曾经有同样问题的人
下面的代码最终成功了
function sendTweets(final_tweet) {
return new Promise ((resolve, reject) => {
client.post('statuses/update', final_tweet, function(error, tweet, response) {
if (error) {
reject(error);
}
resolve(response);
});
});
}
(async () => {
while (1) {
var final_tweet = { // Create tweet struct
status: "Hi!"
}
await sendTweets(final_tweet);
await sleep.sleep(4);
}
})().catch(e => { console.error(e) }) // Catch needed to prevent "Unhandled Promise Rejection" error
非常感谢@knobiDev @TARN4TION @Nitin Goyal
【问题讨论】:
标签:
javascript
node.js
api
loops
async-await
【解决方案1】:
您必须在 async 中放置 while 循环并使用 await for 语句才能同步执行它们。
您可以将 while 包裹在 async 中,如下所示并省略不必要的 sendOff() 方法。您还应该将 final_tweet 作为参数传递。
function sendTweets(final_tweet) {
return new Promise ((resolve, reject) => {
client.post('statuses/update', final_tweet, function(error, tweet, response) {
if (error) {
reject(error);
}
resolve(response);
});
});
}
(async () => {
while (1) {
var final_tweet = { // Create tweet struct
status: "Hi!"
}
await sendTweets(final_tweet);
await sleep.sleep(4);
}
})()
【解决方案2】:
您可能已经注意到,您不能在函数范围之外使用 await。
如果您要将 while 循环放在异步函数中,您可以在其中等待 sendOff,它应该可以工作。
(async () => {
while (true) {
var final_tweet = { // Create tweet struct
status: "Hi!"
}
await sendOff();
}
})();
使用 JavaScript 的 Arrow Functions 来避免声明新函数。
您还必须全局声明final_tweet,因为它没有在sendTweets 中定义。要么,要么让它成为一个函数参数。 (@Nitin Goyal 在他的回答中正是这样做的)
所以:
var final_tweet;
function sendTweets() {
...
}
...
(async () => {
while (true) {
// notice the missing 'var'; we're assigning the new Object to the global final_tweet
final_tweet = { // Create tweet struct
status: "Hi!"
}
await sendOff();
}
})();
【解决方案3】:
function sendTweets(final_tweet) {
return new Promise ((resolve, reject) => {
client.post('statuses/update', final_tweet, function(error, tweet, response) {
if (error) {
reject(error);
}
resolve(response);
});
});
}
async function sendOff(final_tweet ) {
await sendTweets(final_tweet );
}
(async () => {
while (1) {
var final_tweet = { // Create tweet struct
status: "Hi!"
}
await sendOff(final_tweet);
sleep.sleep(4);
})()