我正在使用 React,并且在連續同步點擊時遇到問題(onClick 事件):
我的按鈕觸發了一個呼叫兩個函式resetViews并且chargeViews(chargeViews需要時間)的函式,所以當我快速單擊兩次時:
resetView執行得很好(它設定viewsRef.current為空)- then
chargeViews被呼叫,但由于它需要時間,因此不會立即更新viewsRef.current。 - so
resetView被呼叫但viewsRef.current仍然為空(因為chargeViews還沒有更新它)所以它什么也不做, - 然后我得到了兩次延遲執行
chargeViews - 所以點擊兩次后,我得到了 1 次執行
resetView和 2 次延遲執行chargeViews
我想要的是點擊后,阻止一切(即使用戶點擊我們什么也不做)然后執行resetView然后chargeViews解除阻止以接收另一次點擊并做同樣的作業。
<MyButton onClick={() => {
resetViews();
chargeViews();
}}>
Click me
</MyButton>
需要時間的功能
const chargeViews = () => {
if(!viewsRef.current){
...
reader.setUrl(url).then(()=>{
reader.loadData().then(()=>{
...
viewsRef.current = reader.getData();
})})
}}
如果我點擊這么快就會被忽略的功能,(如果我點擊并等待一點然后我再次點擊它作業正常)但是如果我點擊并再次快速點擊它會被忽略。
const resetViews = () => {
if (viewsRef.current){
...
viewsRef.current = null;
}}
uj5u.com熱心網友回復:
我不能完全把握整個問題……如果不需要這么長的文字,這將是一個評論。
無論如何,只要您需要在單擊按鈕后禁用該按鈕,您應該在其 onclick 處理程式的開頭處理它:
$(this.event.target).prop('disabled', true);
并在最后重置它:
$(this.event.target).prop('disabled', false);
一般來說,您所做的在呼叫處理程式內鏈式執行的許多函式方面是正確的。但是這兩個函式似乎有一個 Promise 呼叫.. 在那種情況下,那些不會在等待第一個完成的鏈中執行。
因此,您應該將第二次呼叫作為回呼傳遞給第一次,以便只有在第一次完成作業后才有機會呼叫它。
我希望有人會直截了當地建議如何使異步函式“等待”,以便無論它做什么,在呼叫它時都會等待它完成,然后再評估下一條陳述句。通常只需await在其簽名之前添加,但有一些警告。
uj5u.com熱心網友回復:
首先,您需要將使用 Promise 的函式轉換為異步函式,然后在呼叫它們時等待它們。這將更容易控制執行順序:
const chargeViews = async () => {
if(!viewsRef.current){
...
await reader.setUrl(url);
await reader.loadData();
...
viewsRef.current = reader.getData();
}
}
然后,您需要一個 isExecuting ref,它在其他呼叫正在執行時為 true,在當前沒有執行時為 false:
const isExecuting = useRef(false);
const handleClick = async () => {
if (!isExecuting.current) {
// block other clicks from performing actions in parallel
isExecuting.current = true;
try {
resetViews();
await chargeViews();
} finally {
// unblock other clicks
isExecuting.current = false;
}
}
};
handleClick最后,在 JSX 中使用新創建的函式:
<MyButton onClick={handleClick}>
Click me
</MyButton>
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/453705.html
標籤:javascript 反应 异步
