async-awaitでeventを同期的に書いてみる
/miyamonz/async awaitで何かを待つような処理を同期的に書くを読んでやってみたくなった
ここで試してみるサイクル
1. 要素にマウスカーソルが入ったら
2. 650ms待ち
3. その間にカーソルがずっと要素の中にいたら色を変える
元記事では/miyamonz/usePromiseResolveを使っているが、まずはそれを使わずにさっと書いてみる
code:sample1.tsx
/** @jsx h */
/** @jsxFrag Fragment */
import {h, Fragment, render} from "https://esm.sh/preact@10.5.14";
import {
useState, useEffect, useRef, useCallback
} from "https://esm.sh/preact@10.5.14/hooks";
const app = document.createElement("app");
const shadowRoot = app.attachShadow({mode: "open"});
const close = () => app.remove();
const App = () => {
const message, setMessage = useState("");
const ref = useRef<HTMLDivElement>(null);
const mouseDownPromise = useCallback(() => {
}, []);
useEffect(()=> {
while (true) {
}
}, []);
return (
<div className="container">
<button className="close" onClick={close}>x</button>
<div className="square" ref={ref} />
<span className="message">{message}</span>
</div>
);
};
const Style = () => <style>
.container {
position: absolute;
top: 10vh;
left 10vw;
}
.close {
display: block;
}
.square {
margin: 10px;
background-color: red;
}
.message {
display: block;
}
</style>;
render(<><Style /><App/ ></>, shadowRoot);
11:31:10 いや、これusePromiseResolve()とかのhelper函数なしにベタ打ちするのは大変だな
例えばmousedownの発火を待つ函数は、単純に書くとこうなる
code:ts
const mouseDownPromise = useCallback(() => new Promise<MouseEvent>((resolve) => {
const callback = (e: MouseEvent)=> {
resolve(e);
ref.current.removeEventListener("mousedown", callback);
};
ref.current.addEventListener("mousedown", callback);
}), []);
const event = await mouseDownPromise();
// ...
しかしこれだと、何度も使うことが出来ない
一度だけしかmousedownの発火を待てない
何度も使えるようにするには、毎回Promiseを作り直すよう設計を変える必要がある
それがusePromiseResolve()
だと思う。多分takker.icon
#Promise
#2021-09-19 11:04:53