【发布时间】:2021-01-31 20:51:12
【问题描述】:
想象一下按下按钮时可以点赞的帖子。此按钮会修改远程数据库,因此将点赞关联到特定帖子需要一点时间。
现在,如果用户开始使用此代码快速按下按钮:
state = {
isLiked: false,
}
handlePress = () => {
this.setState(
{
isLiked: !this.state.isLiked,
},
this.handleLike
);
};
handleLike = async () => {
const { postId } = this.props;
try {
console.log(isLiked ? "Liking" : "Disliking")
await db.processLike(postId);
} catch (err) {
// If an error has occurred, reverse the 'isLiked' state
this.setState({
isLiked: !this.state.isLiked,
});
// TODO - Alert the error to the user in a toast
console.log(err);
}
console.log("DONE");
};
由于一切都是异步的,所以有可能看到这种情况:
喜欢
不喜欢
完成
完成
我曾考虑创建一个状态“isLiking”以避免在所有异步作业完成之前运行代码。像这样的:
state = {
isLiking: false,
isLiked: false,
}
handlePress = () => {
if (this.state.isLiking) return; <------------------------------------
this.setState(
{
isLiking: true, <------------------------------------
isLiked: !this.state.isLiked,
},
this.handleLike
);
};
handleLike = async () => {
const { postId } = this.props;
try {
console.log(isLiked ? "Liking" : "Disliking");
await db.processLike(postId);
} catch (err) {
// If an error has occurred, reverse the 'isLiked' state
this.setState({
isLiked: !this.state.isLiked,
});
// TODO - Alert the error to the user in a toast
console.log(err);
}
this.setState({ isLiking: false }); <------------------------------------
console.log("DONE");
};
这样一切正常,但如果用户快速按下按钮,他将无法看到 GUI 变化(喜欢按钮颜色(喜欢红色,如果不喜欢,则白色)),直到描述的所有过程在上面的代码中完成。
我也想过像这样制作一个去抖函数(用于handlePress):
export const debounce = (func, wait, immediate) => {
/*
Returns a function, that, as long as it continues to be invoked, will not
be triggered. The function will be called after it stops being called for
N milliseconds. If `immediate` is passed, trigger the function on the
leading edge, instead of the trailing.
*/
let timeout;
return function () {
let context = this,
args = arguments;
let later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
let callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
...
debuncedHandlePress = debounce(this.handlePress, 500); // Now, when the button is pressed, it will call this function, instead of the original handlePress
但是有了这个,我唯一要做的就是减少得到混乱结果的机会。也就是说,我仍然遇到与第一个代码相同的问题。
有什么想法可以按照我想要的方式来做我得到的结果是有序的并避免等待写入数据库的时间吗?
谢谢。
【问题讨论】:
标签: javascript reactjs react-native asynchronous async-await