javascript - 如何修复 HTTP 请求上的 setTimeout 行为?
问题描述
在我的客户端应用程序中,我使用 Socket IO 来检查未读事件。我向我的后端发出一个请求,它将超时设置为 5 秒,然后继续检查未读事件并发送回任何事件。
// client
socket.on("response", ({ mostRecentMessages }) => {
// do some stuff first
socket.emit("listenForNew", { userId, currentMessagesFromEveryone });
})
// backend
socket.on("listenForNew", ({ userId, currentMessagesFromEveryone }) => {
if (currentMessagesFromEveryone && userId) {
const { MostRecentMessages } = require("./constants/models");
const filteredIds = [];
currentMessagesFromEveryone.forEach(message => {
filteredIds.push(message.conversation._id);
});
console.log("Entered!");
setTimeout(async () => {
const mostRecentMessages = await MostRecentMessages.find({
to: userId,
date: { $gt: connectedUsersAllMessages[userId].timeIn },
conversation: { $nin: filteredIds }
}).populate("to from conversation");
allMessagesSocket.sockets.connected[
connectedUsersAllMessages[userId].socketId
].emit("response", {
mostRecentMessages
});
}, 5000);
}
});
起初,它工作正常。它为大约 4、5 个请求打印Entered!
一次。然后在 6 日,它开始打印Entered!
两次。
为什么会发生这种情况,我做错了什么?
解决方案
我赞成以下方法:
- 等待 X 秒(在我们的用例中为 5 秒)
- 调用异步操作(执行时间未知)
- 等到异步执行完成
- 在执行下一个调用之前再等待 X 秒
实现可能是这样的:
const interval = 5000;
function next() {
setTimeout(async () => myAsyncOperation(), interval);
}
function myAsyncOperation() {
const mostRecentMessages = await MostRecentMessages.find({
to: userId,
date: { $gt: connectedUsersAllMessages[userId].timeIn },
conversation: { $nin: filteredIds }
}).populate("to from conversation");
allMessagesSocket.sockets.connected[
connectedUsersAllMessages[userId].socketId
].emit("response", () => {
mostRecentMessages();
next(); // "next" function call should be invoked only after "mostRecentMessages" execution is completed (or a race condition may be applied)
});
}
next();
我还没有编译这段代码,但我希望这个概念很清楚
推荐阅读
- xcode - LLDB 读取字符串
- html - 何时使用任何
- javascript - get function not working properly with local storage in JSON string
- php - 给定一个数 N,返回能被 3 整除的最大数 <= N
- php - 根据排名查找重复项
- html - 浏览器放大/缩小是否与不同的屏幕尺寸相同?
- java - Android Studio 3.1.3 错误:java.lang.ClassNotFoundException: org.gradle.api.internal.component.Usage
- symfony - 首次设置字段的时间戳
- django - 将 django 网站运行到服务器时,“模块”对象不可迭代
- .htaccess - 使用动态查询字符串将旧格式重写为新的动态等效格式