Scrapboxからマーカーのデータを取得する
マーカーやコメントのデータは、Scrapboxのページに記録される。
Scrapboxプロジェクトの全ページデータを取得してからマーカーを表示すると、以下のような問題が生じる。
サーバーへの負担
Scrapboxサーバーに対して、ページ数分(例えば数百 ~ 数千)のHTTPリクエストが発生する。
リアルタイム性の欠如
マーカーを引いても、新しいマーカーをブラウザに表示させるためには、再び全ページを取得する必要がある。
マーカーをScrapboxに記録するとき、Scrapboxページには[annos://example.com/]のようなリンクが置かれる。
このannos://から始まるリンクによって、Scrapboxプロジェクトから効率的にデータを取得している。
Scrapboxサーバーへの負担を考慮し、HTTPリクエストを1秒あたり1回までに制限している。
p-queueは、Promiseのキューを実装したnpm packageである。 p-queueを利用して、帯域制限付きのFetch APIを実装した。
code: ts
import PQueue from "p-queue";
const fetchQueue = new PQueue({ interval: 5000, intervalCap: 5 });
const queuedFetch = (input: RequestInfo | URL, init?: RequestInit) =>
fetchQueue.add(() => fetch(input, init), { throwOnTimeout: true });
// 使用例
さらに、素早くページを移動しても、Scrapboxとの通信キューが滞留しないようにしている。
以下の疑似コードのように、AbortSignalを監視すれば処理をキャンセルできる。
code: ts
const functionWithFetch = async(signal) => {
// 省略
// fetchする前に、処理のキャンセルを要求されていないか確認する。
if (signal.aborted) {
throw new DOMException("Aborted", "AbortError");
}
const response = await fetch(
// 省略
};
const abortController = new AbortController();
await functionWithFetch(abortController.signal);
// 処理をキャンセルするとき
abortController.abort();