我在SO上搜索了这个主题超过一个小时,找不到像我这样的案例。
我有一个我在Ruby on Rails上开发的Web应用程序。它基于具有多个字段和按钮的表单来执行操作。
这些是示例(我的真实应用程序使用更多功能和更多操作组合): 当Field1改变时,我想执行JS函数function1(),然后执行function2(),然后执行function3()。 当Field2改变时,我想执行JS函数function2(),然后执行function3()。 当Field3改变时,我想执行JS函数function3()。
所有这些JS函数都调用我的控制器中定义的特定操作,并使用AJAX更新表单。我希望function2()只在function1()完成表单更新后才开始执行,否则结果会出错。
由于这些函数调用的控制器方法会向许多其他网站发送API调用,例如Google地理编码或Google时区,因此它们的响应时间无法预测,可能会从几百毫秒到几个不等。秒。
我试过了:
onchange="function1();function2();function3()"
但是这没有用,因为function2()在function1()通过AJAX完成更新之前开始执行,而function3()关于function2()的问题也是如此。
我也尝试过:
onchange="function1();setTimeout(function(){function2();setTimeout(function(){function3()},FUNCTION2_DELAY)},FUNCTION1_DELAY)"
但这也不起作用,因为如果FUNCTION1_DELAY设置得太长,函数2()将不会在FUNCTION1_DELAY到期之前开始执行,而function1()执行速度可能比FUNCTION1_DELAY快得多,如果FUNCTION1_DELAY设置得太短,则函数2( )将在function1()完成function2()运行所需的更新之前开始执行。关于function2()的函数3()也是一样。
我的问题是:有没有更聪明的方法让function2()只在function1()通过AJAX更新表单时才开始执行,而function3()的功能与function2()相同? 我知道我可以创建新的控制器方法,我合并这些函数,比如将function1(),function2()和function3()合并到new_function1(),...等,但这会使我的代码包含重复的操作,并最终使维护更难。所以我宁愿寻找一种更聪明的方法来解决这个问题。
答案 0 :(得分:0)
你需要使用Promises。
基本上就是这样的:
var MyFunction1 = new Promise(
function() {
//do stuff here
}
);
MyFunction1.then(Myfunction2 ...).then(Myfunction3 ...;
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise http://api.jquery.com/promise/
答案 1 :(得分:0)
setTimeout
是异步的,因此不起作用。您可以在函数1的末尾调用函数2,但仍然在函数内部。类似于功能3:
function one(){
...logic...
function two();
}
function two(){
...logic...
function three();
}
function three(){
...logic...
}
或者,你可以创建某种函数队列,只有在当前函数完成时才移动到下一行:
var functionQueue = [
one,
two,
three
];
function next(){
var nextFn = functionQueue.shift();
if( nextFn ){
nextFn();
}
}
function one(){
...logic...
next();
}
// same for two & three
你也可以使用相当强大的promises,让代码更清晰,但是对于这个问题可能有点过分