顺序函数调用,而其中一个使用setTimeout
sequential function call, while one of them uses setTimeout
我想按此顺序调用三个函数someTask1
, someTask2
和someTask3
。但是,函数someTask2
涉及Ajax调用,并且一直使用setTimeout
递归地调用自己,除非返回所需的值。代码看起来像这样:
doListOfTasks: function(myparam){
var someObj = someTask1(myParam);
someTask2(someObj);
someTask3(someObj);
},
someTask2: function(someObj){
$.ajax({
url: "someUrl.do",
type: "POST",
data: ({"id": rowObject.instanceId}),
dataType: "json",
async:false,
success: function(res){
if(res.prop1 != 'desired'){
setTimeout(function(){someTask2(someObj);}, 2000);
}
}
}
);
},
您可能已经猜到了,这段代码的执行在调用someTask3
之前不会等待someTask2
返回。
我希望doListOfTasks
内的代码顺序执行。我该怎么做呢?
另外,我不想在success
回调中硬编码someTask3
。例:我不想这样做:
success: function(res){
if(res.prop1 != 'desired'){
setTimeout(function(){someTask2(someObj);}, 2000);
}else{
someTask3(someObj);
}
}
如何做到这一点?
感谢编辑# 1
问题是无法调用函数…但问题在于同步。我想要someTask2
完成它正在做的任何事情,只有然后才调用 someTask3
。
someTask2
使用setTimeout重复调用自身…我猜这会触发一个新线程,someTask2
在第一次调用后返回…在主线程触发someTask3
。然而,在每次调用setTimeout时,单独的线程会生成(并被杀死),直到满足所需的条件。
这就是为什么当someTask2仍在循环时,对someTask3的调用触发。
您可以在jquery中使用 Deferred
来实现这一点:
$.when(someTask1(), someTask2(), someTask3()).then(successFunc, errorFunc);
您需要返回一个带有promise值的自定义.Deferred
对象。
someTask2: function(someObj)
{
var def = $.Deferred();
$.ajax({
url: "someUrl.do",
type: "POST",
data: ({"id": rowObject.instanceId}),
dataType: "json",
async:false,
success: function(res){
if(res.prop1 != 'desired'){
setTimeout(function(){someTask2(someObj);}, 2000);
}
else
{
def.resolve(res);
}
}
}
);
return def.promise();
}
例如:
function someTask1()
{
var def = $.Deferred();
def.resolve('i''m data resolved from task1');
return def.promise();
}
function someTask2(someObj)
{
var def = $.Deferred();
var count = 0;
var f = function() {
console.log(++count);
if (count > 2) {
def.resolve('whoop we got the value we wanted in task 2 after many tries: ' + count);
}
else
setTimeout(f, 1000);
};
f();
return def.promise();
}
function someTask3()
{
var def = $.Deferred();
def.resolve('and hello from task3!');
return def.promise();
}
var success = function(x) {
console.log('success:', arguments);
};
var error = function() {
console.log('oh no an error occured in one of the tasks.');
};
$.when(someTask1(), someTask2(), someTask3()).then(success , error);
将显示
1
2
3
success: ["i'm data resolved from task1",
"whoop we got the value ...k 2 after many tries: 3",
"and hello from task3!"]
小提琴可用: http://jsfiddle.net/garreh/29SW7/
您可以向someTask2
传递一个回调。例如:
someTask2: function(someObj, callback){
$.ajax({
url: "someUrl.do",
type: "POST",
data: ({"id": rowObject.instanceId}),
dataType: "json",
async:false,
success: function(res){
if(res.prop1 != 'desired'){
setTimeout(function(){someTask2(someObj, callback);}, 2000);
} else {
if (callback != null) {
callback();
}
}
}
}
);
}
然后传递someTask3
作为回调:
someTask2(someObj, function (){ someTask3(someObj); });
相关文章:
- 添加一个setTimeout方法会使jQuery悬停方法忽略setTimeout方法中的函数
- I'我用setTimeout加载脚本,你能找到一个更快的方法吗
- Jasmine:测试setTimeout函数会抛出一个错误
- 为什么在模糊事件处理程序中添加setTimeout会修复“;掩蔽”;另一个单击处理程序的
- setTimeout与mongodb各一个
- setTimeout 导致未捕获的类型错误:数字不是一个函数
- 为什么process.nextTick()在这个“假异步函数”中触发了一个TypeError,而setTimeout()
- 如果我导航到另一个页面,setTimeout 不起作用
- setTimeout 会创建一个无限循环
- 为什么JavaScript setTimeout在另一个选项卡中滞后
- 有没有办法使用一个 setTimeout 而不是多个
- 确保一次只运行一个 setTimeout(处于活动状态)
- JavaScriptforeach循环遍历一个十六进制值数组,使用setTimeout循环遍历背景颜色
- 一个私有对象的函数的setTimeout
- 如何在不使用setTimeout的情况下运行/构建一个简单的计时器
- settimeout正在阻塞事件循环Nodejs检查下一个示例:
- setTimeout仅适用于一个函数
- 为什么定时器setTimeout返回第一个值“;2〃;.代码下方的
- 为什么generator's .next需要一个setTimeout
- 滚动页面与settimeout -我需要添加一个settimeout或延迟到我的代码