私は再帰的なことを行う関数を実装しました。時には非同期に処理する必要があるため、ループを単純に使用することはできず、再帰的な関数呼び出しを使用する必要があります。非常に抽象的スニペットでInternalErrorを防ぎます:再帰が多すぎます
これは次のことを意味します:
function doStuff(){
// async or sync things -> depends on several circumstances
doStuff();
}
doStuff();
これは素晴らしい作品。しかし、あなたが予想しているように、これは、最大再帰呼び出し制限を超えたときに問題を引き起こします。場合によっては、25,000を超えるコールを処理する必要があります。最新のFirefox(50.0a2)でInternalError: too much recursion
が発生します。
私はInternalErrorをキャッチし、タイムアウトしてコールバックを再トリガすることは働くことが判明しました:
function doStuff(){
// async or sync things -> depends on several circumstances
try{
doStuff();
} catch(e if e instanceof InternalError){
setTimeout(function(){
doStuff();
}.bind(this), 25);
}
}
doStuff();
しかし、これはハックと醜いです。したがって、私は、ループ内で何かを処理できず、再帰的な関数呼び出しを使用する必要があるときに、この状況を回避するための好ましい方法は何かを尋ねています。
現在のブラウザでは、長いテールコールの削除が実装されていないため、ループを使用してください。ループは末尾再帰と同じように表現的であり、独自のスタックデータ構造を持つループは非末尾再帰と同じように表現的であることに注意してください。 'setTimeout'を利用しないでください。 – ftor
1.なぜ 'setTimeout'を利用しないのですか?私はそれが醜いのは分かっていますが、これにはどんな機能的な欠点がありますか? 2.ある時点で非同期コードを実行する必要があるので、通常のループを使用することはできません。ループは実行を続けるでしょう... – dude
'setTimeout'は非常に遅いです。しかし、私はあなたの疑似コードを理解していません。 'doStuff'は引数をとらず何も返しません。再帰的なケースはブロックしています。通常のループとまったく同じように動作します。ベースケースはどうですか? – ftor