Sie Ihre conditionals in der asynchronen/verzögerten Zeitplan ausgeführt wird und wenn Sie in dieser Zeitleiste eingeben gibt es keinen Ausweg. Sie müssen dort bleiben, so lange Ihre Logik geht, einschließlich aller rekursiven Aktivitäten. Jedoch würde ich Ihnen raten, Versprechungen zu verwenden und die gesamte Logik zum then
Teil wegen der funktionalen Programmierung zu bewegen.
Lassen Sie uns zuerst unsere Funktionen nacheinander betrachten und sehen, wie sich alle auf die Versprechen einstellen.
OK nehmen wir an, dass wir eine generische async Funktion haben, die waitAndDoStg
genannt wird, die ein Daten und einen Rückruf als zwei seiner Argumente nimmt. Nehmen wir an, unser Callback ist vom ersten Typ Fehler.
var waitAndDoStg = (data,cb) => setTimeout(_=> cb(false, data.value),data.duration),
Es werden niemals Fehler zurückgegeben. Also nach data.duration
Millisekunden pass es ruft unseren Rückruf wie cb(false, data.value)
auf und wird die Daten, die es von uns nahm, an uns zurückgeben. Eine dumme Funktion ist was es ist.
Also ok, wir müssen diese asynchrone Funktion promisfy. Wir haben eine Standard-Promisfy-Utility-Funktion, die jede Async-Funktion übernimmt und uns ein Versprechen gibt. Der Rückruf muss jedoch der erste Fehler sein.
promisfy = (data,func) => new Promise((v,x) => func(data,(err,res) => err ? x(err) : v(res)));
OK, statt resolve
und reject
i jeweils v
und x
Namen verwenden. Nun, ich denke, es ist vernünftig, v
für resolve
zu verwenden, da es wie ein Häkchen aussieht und x
ist in Ordnung für reject
ich nehme an.
Also hier ist der Rest des Codes. Es ist Versprechen und rekursiv und alles, aber ich denke, funktionell ist dies ein sehr lesbarer Code.
var promisfy = (data,func) => new Promise((v,x) => func(data,(err,res) => err ? x(err) : v(res)));
decrementByOne = n => --n,
waitAndDoStg = (data,cb) => setTimeout(_=> cb(false, data.value),data.duration),
countDownPromise = n => {n && console.log(n);
promisfy({value:n, duration:1000}, waitAndDoStg)
.then(decrementByOne)
.then(val => val !== 0 ? countDownPromise(val)
: console.log("Ignition...!"));
};
countDownPromise(3);
Warum? Der Code in 'setTimeout' wird niemals aufgerufen, bis der Code in' checkBrowser' vollständig ist. – aghidini
Anruf Checkbrowser vor dem Einstellen der Timeout? – DarkBee
Ich habe die Frage aktualisiert. Ich habe 2 oder mehr setTimeouts. Und wenn einige.condition wahr ist, die nächsten setTimeouts nicht ausgeführt werden. –