我有一组大约100个参数,这些参数都需要不同的时间来运行给定的函数。每个都是页面上的简短动画,根据参数动画不同的部分,每个动画大约需要1-3秒。
我查了一下:Nested setTimeout alternative?
...但它仅在子功能花费相同的时间时才有效,
我可以按顺序收集数组中的参数,即:
args = [arg1,arg2,arg3,arg4 ...]
目前我的电话如下:
setTimeout(myfunction(arg1), 3000);
setTimeout(myfunction(arg2), 5000);
setTimeout(myfunction(arg3), 7500);
setTimeout(myfunction(arg4), 8500);...
我真的希望能够有代码说“当myfunction(arg1)完成时,等待500毫秒然后执行myfunction(arg2),然后当完成时等待500毫秒并执行func3等。 “
我不知道如何将其纳入setTimeouts的运行或myfunction()的定义。
谢谢。
答案 0 :(得分:1)
您可以在上一个setTimeout
的回调中安排下一个任务,如下所示:
var tasks = [
{ arg : "arg1", delay : 3000},
{ arg : "arg2", delay: 2000},
{ arg : "arg3", delay : 2500}
];
function myFunction(arg) {
console.log(new Date(),arg);
}
function schedule() {
var task = tasks.shift();
if(task) {
setTimeout(function() {
myFunction(task.arg);
if(tasks.length) schedule();
},task.delay);
}
}
schedule();
此代码将在3000毫秒内调用myFunction("arg1")
,然后在+ 2000毫秒内调用myFunction("arg2")
,然后在+ 2500毫秒调用myFunction("arg3")
。
每次删除(移动)“任务列表”的第一个元素时, 然后一旦它是空的就停止。
请注意,此代码将改变您的tasks
数组(通过在每次迭代时从中移除下一个任务),因此您将无法重复使用它。
如果这是一个问题,只需使用显式索引来解决下一个任务:
function schedule(tasks,i) {
if(i<tasks.length) {
setTimeout(function() {
myFunction(tasks[i].arg);
if(i+1<tasks.length) schedule(tasks,i+1);
},tasks[i].delay);
}
}
schedule(tasks,0);
答案 1 :(得分:1)
Promises
是链接异步操作的完美方式。
如果您可以考虑更改myFunction
的正文以便它返回promise
,那么您可以轻松地链接这些操作。
myFunction
的正文看起来像这样
function myFunction(args, time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// here you do your stuff
resolve(); // resolve the promise when it's done
}, time);
})
}
你这么称呼它
var args = [
{ args: "", timeout: 100 },
{ args: "", timeout: 300 }
]
var promise = Promise.resolve();
args.forEach(function (animation) {
promise = promise
.then(myFunction.bind(null, animation.args, animation.timeout))
// ^ chaining promise so that they fire one after another
})
答案 2 :(得分:0)
我认为解决这个问题的最简单方法是承诺链:
var args = [1, 2, 3, 4, 5, 6]
var i = 0;
function doStuff(arg) {
//do stuff
console.log(arg)
}
function getPromise(cb, arg, time){
return function() {
return new Promise(function(resolve){
setTimeout(function(){
cb(arg)
resolve()
}, time)
})
}
}
var promise_chain = Promise.resolve();
while (args[i]) {
promise_chain = promise_chain.then(getPromise(doStuff, args[i++], 500))
}
此代码将生成一堆承诺。每个人等待500ms来解决自己并执行下一堆代码。希望这有帮助。