我正在开发一个聊天应用程序,它会在用户通过按 Enter
发送聊天消息(一个 React 组件)后立即呈现它。 :
在这里,输入 ABC
后然后按 Enter
,React 组件的状态会立即更新并呈现消息以避免 UI 缓慢。
然后发出 AJAX 请求。 AJAX 将消息发送到服务器,如果chat_id
,服务器又创建一个新的聊天。为 0(聊天的第一条消息),保存消息并返回新创建聊天的 ID。
此时,聊天已使用服务器返回的 ID 更新。下面是一段代码:
class ChatApp extends React.Component {
// ...
constructor(props) {
super(props)
this.state = {
currentChat: {
id: 0, // 0 means "this is a new chat"
messages: [],
// ...
}
}
}
handleSendMessage(message) {
this.setState((prevState) => {
const pendingCurrentChat = {
...prevState.currentChat,
messages: prevState.currentChat.messages.concat([{
message
}])
}
return {
currentChat: pendingCurrentChat
}
}, () =>
this.setState((state) => {
const currentChat = state.currentChat
const currentChatId = currentChat.id
// AJAX call starts here:
const params = {
act: 'handleSendMessage',
message: message,
chat_id: currentChatId
}
this.POST(params, JSONResponseData =>
this.setState((prevState) => {
const chatId = JSONResponseData.chat_id
const currentChat = {
...prevState.currentChat,
id: chatId
}
const newState = {
currentChat
}
return newState
})
)
// No state change here.
return null
})
)
}
// ...
}
这种方法的问题是,如果聊天是新的 (currentChat.id == 0
),用户通过键入并按 Enter
发送一堆消息很快,出现竞争条件,一些 AJAX 请求使用 chat_id: 0
重叠导致在服务器端创建多个聊天:
在这里,我输入了 a
并快速输入,我最终在服务器端创建了多个聊天,因为有几个请求是用 chat_id
发出的设置为 0
.
我如何确保只有聊天的第一条消息发送到服务器 chat_id: 0
如果用户以快速方式打字而不会遇到竞争条件?
我只能想到:
- 在客户端生成 ID(可能是 UUID),然后发送到服务器。我真的不想让用户在呈现第一条消息之前等到第一个 AJAX 完成;
- 在让用户发送消息之前创建一个新聊天。不过,即使用户可能没有发送第一条消息,我也会通过这种方式在服务器上使用 ID;
例如,Facebook 的 Messenger 具有我正在寻找的行为:当您发送一条消息时,只要您按下 Enter
,它就会立即呈现。 ,他们如何处理?通过查看网络选项卡,他们似乎提前创建了一个 ID,但我不确定:
您将如何在 UI/UX 和服务器端数据持久性方面处理这个问题?
最佳答案
我会生成一个 id 客户端,它会持续存在,直到获取响应被解决。
然后,如果客户端 ID 与刚刚创建的新聊天相同,请不要创建新聊天,将新消息存储在某个地方,直到您拥有新的服务器 ID,然后将它们推送到网上。
关于javascript - 仅在 AJAX 调用后才知道其 ID 时如何呈现 React 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56796726/