코드 블록이 동시에 실행되지 않도록하고 싶습니다. async-Mutex 라이브러리가 나를 위해 작동하지 않는 것 같습니다. 다음은 최소한의 복제입니다.
/* eslint-disable */
import React, { useState, useEffect } from "react";
var Mutex = require("async-mutex").Mutex;
const Timer = () => {
const [isActive, setIsActive] = useState(false);
const mutex = new Mutex();
useEffect(() => {
mutex.runExclusive(async function () {
console.log("starting", isActive);
await new Promise((resolve) => setTimeout(resolve, 1000));
console.log("ending", isActive);
});
}, [isActive]);
return (
<div className="app">
<button onClick={() => setIsActive((prev) => !prev)} type="button">
{isActive ? "Active" : "Inactive"}
</button>
</div>
);
};
export { Timer as default };
버튼을 빠르게 두 번 클릭하면 인쇄되는 것을 볼 수 있습니다.
starting
true
starting
false
starting
true
ending
true
ending
false
이것들이 인터리브 된 것을 볼 수 있습니다.
이것을 동시에 실행하지 않도록하려면 어떻게해야합니까?
import React, { useState, useEffect, useRef, useMemo} from "react";
var Mutex = require("async-mutex").Mutex;
const Timer = () => {
const [isActive, setIsActive] = useState(false);
const mutex = useRef(new Mutex());
// Or another way, it might be a bit more performant,
// although the Mutex class has an almost empty constructor
// const mutex= useMemo(()=> new Mutex(), []);
useEffect(() => {
mutex.current.runExclusive(async function () {
console.log("starting", isActive);
await new Promise((resolve) => setTimeout(resolve, 1000));
console.log("ending", isActive);
});
}, [isActive]);
return (
<div className="app">
<button onClick={() => setIsActive((prev) => !prev)} type="button">
{isActive ? "Active" : "Inactive"}
</button>
</div>
);
};
export { Timer as default };
이전 함수 호출을 취소하고 마운트 해제시 비동기 루틴 정리를 지원하려는 경우 ( Demo ) :
/* eslint-disable */
import React, { useState, useEffect } from "react";
import CPromise from "c-promise2";
import { useAsyncEffect, useAsyncCallback } from "use-async-effect2";
export default function Timer() {
const [isActive, setIsActive] = useState(false);
const callback = useAsyncCallback(
function* () {
console.log("starting", isActive);
yield CPromise.delay(1000);
console.log("ending", isActive);
},
{ combine: true }
);
useAsyncEffect(
function* () {
console.log("mount");
yield callback();
},
[isActive]
);
return (
<div className="app">
<button onClick={() => setIsActive((prev) => !prev)} type="button">
{isActive ? "Active" : "Inactive"}
</button>
</div>
);
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다