我很难弄清楚如何编写这段代码......
function myFunction(x,y,z) {
// do some stuff here (code block A)
// then some stuff here (code block B)
// but...
if (y == 73) { // y isn't always 73...
// I need more data from the server before I can complete this function
$.getJSON("data.php", {y: 73, z: z}, function(data) { ... });
}
// and finally some other code down here (code block C)
// And done!
$.post("data.php", {data: someVariable}, callbackFx);
}
所以我遇到的概念问题是,在我意识到需要从服务器获取更多来自给定输入的数据后,我想要执行代码(代码块C)。它不会一直发生,但我基本上想暂停执行。我们都知道同步AJAX是一种犯罪行为,可以通过Javascript神的鞭打来惩罚。
起初我认为代码块C应该只是进入它自己的函数,但它会变得混乱,因为在上面的其余代码中代码块C中存在许多依赖关系。
所以我考虑使用deferred / promise,但是如果AJAX并不总是必然发生的话,如何将代码作为承诺执行呢?
if (y == 73) {
var deferred = $.getJSON("data.php", {y: 73, z: z}, function(data) { ... });
deferred.always(function() { ... });
}
else {
// that function in the deferred never gets called
}
我能想到的最接近“好答案”的是以下(但我不知道它是否真的是一个“好的答案”)......
var codeBlockC = function() { ... };
if (y == 73) {
var deferred = $.getJSON("data.php", {y: 73, z: z}, function(data) { ... });
deferred.always(codeBlockC);
}
else {
codeBlockC();
}
然后存在范围和闭包以及东西的问题。有任何想法吗?我只需要完全重新组织我的方式吗?
答案 0 :(得分:3)
更简单的方法是将代码块C 的功能放在嵌套函数中。 JavaScript具有词法范围,因此所有需要的数据仍然可用。
例如:
function myFunction(x,y,z) {
// do some stuff here (code block A)
// then some stuff here (code block B)
var codeBlockC = function() {
// code in here can access all variables from code blocks A and B
// everything after the potential Ajax call needs to be in here
// and finally some other code down here (code block C)
// And done!
$.post("data.php", {data: someVariable}, callbackFx);
};
// but...
if (y == 73) { // y isn't always 73...
// I need more data from the server before I can complete this function
$.getJSON("data.php", {y: 73, z: z}, function(data) {
codeBlockC(); // execute as callback
});
} else {
codeBlockC(); // execute immediately
}
}
答案 1 :(得分:2)
你总是可以从假承诺开始:
var def = { always: function(f) { f(); } };
if (whatever) {
def = $.get( ... whatever ... );
}
def.always(function() {
$.post( ... whatever ... );
}
我想这就是你的基本问题,所以答案是肯定的:-)只做自己的。当然,如果您觉得它会发生很多事情,您可以将其定义为全球服务。
我想你也可以从一个合法构造的“延期”对象开始,你可以立即解决它。
答案 2 :(得分:1)
虽然我认为我更喜欢lwburk答案的简单性,但您也可以创建自己的方法作为延迟方法。这为更复杂的情况提供了更多的灵活性。有关设置的信息,请参阅jQuery Deferred Object for more info,但这里是您的示例:
function myFunction(x,y,z) {
var deferredFunction;
// do some stuff here (code block A)
// then some stuff here (code block B)
//define your own function that is deferred
deferredFunction = function () {
var defer = $.Deferred();
if (y == 73) {
$.getJSON("data.php", {y: 73, z: z}, function(data) {
//your code...
defer.resolve();
});
} else {
defer.resolve();
}
return defer.promise();
}
//now execute the your function and when it resolves execute the rest of the code
deferredFunction().then(function () {
// and finally some other code down here (code block C)
// And done!
$.post("data.php", {data: someVariable}, callbackFx);
});
}