Promise创建及控制执行
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()
}
利用上述控制我们举一个小例子
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>
);
}
从上面一个例子中我们可以完美的跨组件拿到对方异步执行结果,从而做数据处理。这篇文章也是借鉴了我的之前的一篇文章《Solidjs状态更新管理在React中的应用》