マイクロタスク・リカバリ・トリック
7417 ワード
Recursion is an operation that a lot of developers are trying to avoid since it is very dangerous, and can break the execution of applications in a fraction of a bug, but it is needed in some scenarios (e.g tree iteration). This post is for technical readers who want to learn how to use recursion efficiently using Microtasks. I assume that you're already familiar with JavaScript event loop mechanism
それで、私の話はあまり長くありません、そして、私が木オブジェクトを横断するためにコードを書く必要があったとき、私の最後の週末に始まりました.
私は再帰的なロジックでコードを作成する必要があったので、スタックが最大スタックフレームに制限されているため、スタックオーバーフロー(RangeError例外)を避けるためにコードを分割する必要がありました.
ブラウザのスタックの制限を確認できますhere
当然、私はタイミングAPI(settimeout/setinterval)を使って反復を「中断」する必要があることを知っていました.
function run() {
const max = 50000;
let count = 0;
const start = performance.now();
(function run() {
if (count < max) {
count++;
if (count % 100 === 0) {
setTimeout(run, 0);
} else {
run();
}
} else {
console.log(`Done: ${performance.now() - start}`);
}
})();
}
私がこの与えられたコードの実行時間をチェックしたとき、私はあまり幸せでなかった(~ 2500 ms)、そして、私はより良い結果を得たかったです.私は、私の問題に対するより良いアプローチについて考えていました.タイミングAPIの使い方をマイクロタスクに置き換えました.
function run() {
const max = 50000;
let count = 0;
const start = performance.now();
return new Promise((resolve) => {
(function _run() {
if (count < max) {
count++;
if (count % 100 === 0) {
queueMicrotask(_run);
} else {
_run();
}
} else {
console.log(`Done: ${performance.now() - start}`);
resolve(performance.now() - start);
}
})();
});
}
このパターンの実行時間は675.6倍速くなった!(3.7 ms)Microtask使用方法は、2つの主要な理由でこのようなシナリオをよりよく動作させます.
タイミングAPIは決定的ではない
queueMicrotask
によるとprocessing model algorithm , the micro-tasks execution アルゴリズムは高速かつ効率的です.スタックが空であるならば、それがするすべてはすべてのマイクロ作業を実行することです(待ち行列管理でない).
結論
JavaScriptは、重い計算や再帰論理のための言語ではありませんが、できるだけ早く再帰的実行を実行する必要がある場合.
スタックサイズの制限なしで、マイクロタスクを使用するのに役立ちます.
Reference
この問題について(マイクロタスク・リカバリ・トリック), 我々は、より多くの情報をここで見つけました https://dev.to/bgauryy/js-microtask-recursion-trick-1akcテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol