Promise creation and control execution
const context = []; function subscribe(running, subscriptions) { subscriptions.add(running); running.dependencies.add(subscriptions); } export function createSignal() { const subscriptions = new Set(); let handler; const read = () => { const running = context[context.length - 1]; if (running) subscribe(running, subscriptions); return new Promise((r) => handler = r); }; const write = () => { for (const sub of [...subscriptions]) { sub.execute(handler); }}; return [read, write]; } function cleanup(running) { for (const dep of running.dependencies) { dep.delete(running); } running.dependencies.clear(); } export function createEffect(fn) { const execute = (cal) => { cleanup(running); context.push(running); try { fn(cal); } finally { context.pop(); }}; const running = { execute, dependencies: new Set() }; execute(); }Copy the code
Let’s take a small example using the above controls
const [getPromise, setPromise] = createSignal();
const [getPromise1, setPromise1] = createSignal();
function Grade() {
const [grade, setGrade] = useState(0);
const gradeRef = useRef(0);
gradeRef.current = grade;
useEffect(() => {
createEffect((hanlder) => {
getPromise();
if (hanlder) {
setTimeout(() => hanlder(gradeRef.current), 1000)
}
console.log('getPromise')
})
}, [])
const handleAdd = () => {
setGrade(c => c+1);
getPromise1().then((res) => {
console.log(res,'res1=====123')
});
setPromise1();
}
return (
<div>
<div>{grade}</div>
<div onClick={handleAdd}>add</div>
</div>
)
}
function Counter() {
const [count, setCount] = useState(0);
const countRef = useRef(0);
countRef.current = count;
useEffect(() => {
createEffect((hanlder) => {
getPromise1();
if (hanlder) {
setTimeout(() => hanlder(countRef.current), 1000)
}
console.log('getPromise')
})
}, [])
const handleAdd = () => {
setCount(c => c+1);
getPromise().then((res) => {
console.log(res,'res=====123')
});
setPromise();
}
return (
<div>
<div>{count}</div>
<div onClick={handleAdd}>add</div>
</div>
)
}
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<Counter />
<Grade />
</header>
</div>
);
}
Copy the code