问题描述
我的代码:
<?php
if(isset($_GET['m'])) {
$m = $_GET['m'];
sleep($m);
print "done, m=$m";
die;
}
?>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script>
<script>
function w(s) {
document.body.innerHTML = document.body.innerHTML+ "<br>" + s
}
function aaa(def) {
w("begin aaa");
$.ajax({
type: "GET",
data: {
m: 5
}
}).done(function(html) {
w(html);
def.resolve();
});
}
function bbb(def) {
w("begin bbb");
$.ajax({
type: "GET",
data: {
m: 1
}
}).done(function(html) {
w(html);
def.resolve();
});
}
$(function() {
$.when(
$.Deferred(function(d) { aaa(d) }).promise(),
$.Deferred(function(d) { bbb(d) }).promise()
).done(function() {
w("OK")
});
})
</script>
我希望第二个函数等待第一个函数完成,也就是说,我的输出应该是
begin aaa
<--pause
done, m=1
begin bbb
<--pause
done, m=5
OK
相反,我得到了
begin aaa
begin bbb
<--pause
done, m=1
<--pause
done, m=5
OK
我想我误解了延期工作的基本原理-任何人都可以找到答案吗?
如果它们之间没有依赖性,您如何期望它们按顺序执行? $.when
对承诺的评估没有影响,也没有影响,它只是等待每个承诺都得到解决.
您的代码要复杂得多. $.ajax
已经返回了一个Promise,当收到Ajax响应时,它会被解决,因此您只需从函数中将其返回即可.如果要按顺序执行它们,可以通过 .then
:
因此您的代码简化为:
function aaa() {
w("begin aaa");
return $.ajax({
type: "GET",
data: {
m: 5
}
}).done(w);
}
function bbb() {
w("begin bbb");
return $.ajax({
type: "GET",
data: {
m: 1
}
}).done(w);
}
aaa().then(bbb).done(function() { w('ok'); });
在这里,aaa().then(bbb)
创建您需要的依赖项.这基本上意味着一旦aaa
的承诺得到解决,就执行bbb
".另外,.then
返回一个新的promise,当bbb
返回的promise被解析时,该新promise将被解析,这使您可以在aaa
和bbb
的promise都被解析时执行一个函数. >
也许这些可以帮助您更好地理解承诺(和延期):
不带$.ajax
的示例:
function aaa() {
var def = new $.Deferred();
setTimeout(function() {
def.resolve(21);
}, 3000);
return def.promise();
}
function bbb(v) {
var def = new $.Deferred();
setTimeout(function() {
def.resolve(v * 2);
}, 1000);
return def.promise();
}
// aaa -> bbb -> console.log
// The value is logged after 3 + 1 seconds
aaa().then(bbb).done(function(v) { console.log(v); }); // 42
// (aaa | bbb) -> console.log
// The value is logged after max(3, 1) seconds and both resolved values are
// passed to the final promise
$.when(aaa(), bbb(5)).done(function(v) { console.log(v); }); // [21, 10]
My code:
<?php
if(isset($_GET['m'])) {
$m = $_GET['m'];
sleep($m);
print "done, m=$m";
die;
}
?>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script>
<script>
function w(s) {
document.body.innerHTML = document.body.innerHTML+ "<br>" + s
}
function aaa(def) {
w("begin aaa");
$.ajax({
type: "GET",
data: {
m: 5
}
}).done(function(html) {
w(html);
def.resolve();
});
}
function bbb(def) {
w("begin bbb");
$.ajax({
type: "GET",
data: {
m: 1
}
}).done(function(html) {
w(html);
def.resolve();
});
}
$(function() {
$.when(
$.Deferred(function(d) { aaa(d) }).promise(),
$.Deferred(function(d) { bbb(d) }).promise()
).done(function() {
w("OK")
});
})
</script>
I'm expecting the second function to wait for the first one to complete, that is, my output should be
begin aaa
<--pause
done, m=1
begin bbb
<--pause
done, m=5
OK
Instead I'm getting
begin aaa
begin bbb
<--pause
done, m=1
<--pause
done, m=5
OK
I guess I'm misunderstanding something fundamental about how deferreds work - can anyone shed a light?
How do you expect them to be executed in order if there is no dependency between them? $.when
doesn't have and cannot have an influence on the evaluation of the promise, it just waits until each of the promises is resolved.
Your code is way more complicated then it needs to be. $.ajax
already returns a promise which gets resolved when the Ajax response was received, so you can just return it from the functions. If you want to execute them in sequence, you can chain them via .then
:
So your code simplifies to:
function aaa() {
w("begin aaa");
return $.ajax({
type: "GET",
data: {
m: 5
}
}).done(w);
}
function bbb() {
w("begin bbb");
return $.ajax({
type: "GET",
data: {
m: 1
}
}).done(w);
}
aaa().then(bbb).done(function() { w('ok'); });
Here, aaa().then(bbb)
creates the dependency you need. It basically means "once aaa
's promise is resolved, execute bbb
". In addition, .then
returns a new promise, which gets resolved when the promise returned by bbb
gets resolved, which allows you to execute a function when the promises of both, aaa
and bbb
are resolved.
Maybe these help you to understand promises (and deferreds) better:
Example without $.ajax
:
function aaa() {
var def = new $.Deferred();
setTimeout(function() {
def.resolve(21);
}, 3000);
return def.promise();
}
function bbb(v) {
var def = new $.Deferred();
setTimeout(function() {
def.resolve(v * 2);
}, 1000);
return def.promise();
}
// aaa -> bbb -> console.log
// The value is logged after 3 + 1 seconds
aaa().then(bbb).done(function(v) { console.log(v); }); // 42
// (aaa | bbb) -> console.log
// The value is logged after max(3, 1) seconds and both resolved values are
// passed to the final promise
$.when(aaa(), bbb(5)).done(function(v) { console.log(v); }); // [21, 10]
这篇关于如何顺序调用延迟函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!