jQuery Deferred and Promise dla sekwencyjnego wykonywania funkcji synchronicznych i asynchronicznych
Jeśli chcę, aby funkcje synchroniczne i asynchroniczne były wykonywane w określonej kolejności, mógłbym użyć obietnicy jQuery, ale wydaje się, że nie działa tak, jak powinienem.
Funkcje a, b i c powinny być wykonywane w tej kolejności, gdy są wdeferred.resolve()
jest nazywane Spodziewam się, że funkcja b zostanie wykonana, ale wszystkie funkcje zostaną wykonane natychmiast, niezależnie od tego, czy wywołanie jest wywoływane.
Oto kod:
function a(){
var deferred = $.Deferred();
setTimeout(function(){
console.log("status in a:",deferred.state());
//this should trigger calling a or not?
deferred.resolve("from a");
},200);
console.log("a");
return deferred.promise();
};
function b(){
var deferred = $.Deferred();
setTimeout(function(){
console.log("status in b:",deferred.state());
deferred.resolve("from b");
},200);
console.log("b");
return deferred.promise();
}
//synchronous function
function c(){
var deferred = $.Deferred();
console.log("c");
console.log("status in c:",deferred.state());
deferred.resolve("from c");
return deferred.promise();
}
function test(){
fn=[a,b,c],i=-1,
len = fn.length,d,
d = jQuery.Deferred(),
p=d.promise();
while(++i<len){
p=p.then(fn[i]);
}
p.then(function(){
console.log("done");
},
function(){
console.log("Failed");
});
d.resolve();
//instead of the loop doing the following has the same output
//p.then(a).then(b).then(c);
//d.resolve();
}
test();
Wyjście to:
a
b
status in c: pending
c
done
status in a: pending
status in b: pending
Oczekiwany wynik:
a
status in a: pending
b
status in b: pending
c
status in c: pending
done
Wypróbowałem kilka kombinacji następujących modyfikacji:
d = jQuery.Deferred();
setTimeout(function(){d.resolve();},100);
var p=d.promise();
while(++i<len){
p.then(fn[i]);
}
Ale wszystkie z tymi samymi nieoczekiwanymi rezultatami, b zostaje wywołane, zanim zostanie rozwiązane odroczenie a, c zostaje wywołane, zanim zostanie odroczone b.