首页 > 解决方案 > 避免通过用户事件并行执行函数体,直到完成先前触发的执行 - Javascript

问题描述

在我的组件实现中,doSomething函数在用户单击按钮时触发。问题是doSomething需要大约 200-1100 毫秒才能完成执行状态更改。我面临快速按钮单击同时触发此功能体的问题,这会导致意外的最终状态。

不需要复杂的互斥解决方案。要求只是在当前执行完成之前忽略所有其他调用,我尝试了以下标记方法:

doSomething = () => {
    if(this.running){
        return //ignore the event
    }
    this.running=true;
    //do processing
    this.setState({someVariable:answer_of_process}, ()=>this.running=false);
}

render(){
    return(<ImportedComponent doSomething={this.doSomething}/>)
}

这降低了国家腐败的可能性,但偶尔会发生。即:之前 20% 现在 2%。如何将此解决方案改进为 0% 的故障率?

编辑: 功能触发按钮来自导入的复杂组件,无法禁用。该组件将doSomething作为道具。

标签: javascriptreactjsasync-await

解决方案


猜测您只需要在触发多个事件后的特定时间段内执行最后一个操作。

属于去抖功能领域。

创建一个去抖动函数,该函数延迟调用函数,直到自上次调用去抖动函数后等待毫秒过去。


例如:如果用户输入非常快,并且请求花费数倍,我们希望只触发最后一个用户输入值。

import React, { useState, useCallback } from "react";
import "./styles.css";
import { debounce } from "lodash";

const request = debounce(value => {
  alert(`request: ${value}`);
}, 1000);

export default function App() {
  // const [input, setInput] = useState("");
  const debouceRequest = useCallback(value => request(value), []);
  const onChange = e => {
    // setInput(e.target.value);
    debouceRequest(e.target.value);
  };
  return (
    <div className="App">
      <input onChange={onChange} />
      {/* {input} */}
    </div>
  );
}

编辑 elated-dawn-lb5ex


推荐阅读