Javascript 在 setTimeout 完成后运行下一个函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30364849/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
run next function after setTimeout done
提问by bsbak
How to make it work? pls help.
如何使它工作?请帮忙。
function first() {
setTimeout((function() {
$('#q').append('first <br>');
}), 1000);
}
function second() {
$('#q').append('second <br>');
}
function third() {
$('#q').append('third <br>');
}
$.when(first()).done(second()).done(third());
first() runs as last function, i need as first
first() 作为最后一个函数运行,我需要作为第一个
Fiddle here: JSFIDDLE
在这里小提琴:JSFIDDLE
采纳答案by Zee
I am not sure why are you doing this, but if you want to execute them synchronously, you can place the 2nd and 3rd function call inside setTimeout:
我不确定你为什么要这样做,但如果你想同步执行它们,你可以将第二个和第三个函数调用放在里面setTimeout:
function first() {
setTimeout(function() {
$('#q').append('first <br>');
second();
third();
}, 1000);
}
function second() {
$('#q').append('second <br>');
}
function third() {
$('#q').append('third <br>');
}
first();
回答by John
EDIT:
编辑:
You can now also try async/await(doesn't support IE) awaiting the timeout promise before executing first second and third. fireEventsis our async function in this example. Notice how since fireEventshas the asynckeyword before the function that it is able to use the awaitkeyboard. Await keywords allow you to await the finishing of a promise. Here there is a small promise wrapper using the Promiseconstructor around setTimeout which is returned from the function timeoutthis timeoutfunction is awaited inside of the async function fireEvents. The commented numbers below show order of the execution. For deeper knowledge on Promise execution order you can read Jake Archibald's wonderful article Tasks, microtasks, queues and schedules.
您现在还可以尝试async/await(不支持 IE)在执行第一第二和第三之前等待超时承诺。fireEvents在这个例子中是我们的异步函数。请注意,在可以使用键盘的函数之前,sincefireEvents是如何使用async关键字的await。Await 关键字允许您等待承诺的完成。这里有一个小许的包装采用无极周围的setTimeout构造函数从该函数返回timeout该timeout函数是异步函数中等待fireEvents。下面的注释数字显示了执行的顺序。要更深入地了解 Promise 执行顺序,您可以阅读 Jake Archibald 的精彩文章任务、微任务、队列和计划。
function timeout (ms) {
return new Promise(res => setTimeout(res,ms));
}
function first () {
// $('#q').append('first <br>');
console.log("first");
}
function second() {
// $('#q').append('second <br>');
console.log("second");
}
function third() {
// $('#q').append('third <br>');
console.log("third");
}
async function fireEvents () {
// 2
console.log("2. before await")
await timeout(1000);
// 4
console.log("4. after await")
first();
second();
third();
}
// 1
console.log("1. started");
fireEvents().then(()=>{
// 5
console.log("5. done")
});
// 3
console.log("3. after fireEvents");
Original Answer
原答案
You don't need jquery's deferred when you can use javascript promisesinstead.
当您可以使用 javascript承诺时,您不需要 jquery 的延迟。
function first() {
return new Promise(function(resolve, reject) {
setTimeout((function() {
$('#q').append('first <br>');
resolve("Stuff worked!");
}), 1000);
});
}
function second() {
$('#q').append('second <br>');
}
function third() {
$('#q').append('third <br>');
}
first().then(second).then(third);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="q"></div>
Another way of executing the last line first().then(second).then(third);is by making it
执行最后一行的另一种方法first().then(second).then(third);是使它
first().then(function () {
second();
third();
});
which you can do since you know the second and third functions are synchronous functions unlike the first function which is asynchronous.
您可以这样做,因为您知道第二个和第三个函数是同步函数,而第一个函数是异步函数。
EDIT: The reason behind using a javascript promise or in guest271314's answer a jquery defer is because if you wanted to reuse first but call something besides first or second after it's done in a different part of your code you could just write something to the effect of
编辑:使用 javascript 承诺或在来宾 271314 的回答中使用 jquery defer 的原因是因为如果您想先重用但在代码的不同部分完成后调用除 first 或 second 之外的其他内容,您可以编写一些效果
first().then(function () {
fourth();
fifth();
});
And you would be writing that without changing the function for first. Promises and deferreds make async code more reusable.
你会在不改变函数的情况下编写它。Promises 和 deferreds 使异步代码更可重用。
回答by guest271314
Try utilizing $.Deferred()within first, return $.Deferred()jQuery promise when setTimeoutcompletes , call second, thirdwithin .done()
尝试利用$.Deferred()内first,返回$.Deferred()jQuery的承诺时setTimeout完成,通话second,third内.done()
function first() {
var d = new $.Deferred();
setTimeout((function() {
$('#q').append('first <br>');
d.resolve()
}), 1000);
return d.promise()
}
function second() {
return $('#q').append('second <br>');
}
function third() {
return $('#q').append('third <br>');
}
$.when(first()).done([second, third]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id='q'></div>
jsfiddle http://jsfiddle.net/hqphbhx3/1/
jsfiddle http://jsfiddle.net/hqphbhx3/1/
回答by Drakes
If you want to isolate the functions, try this. You pass in a callbackto the firstfunction, and when the timer times out, that callback is called. In that callback you can call second()and third().
如果你想隔离功能,试试这个。您将 a 传递callback给该first函数,当计时器超时时,将调用该回调。在该回调中,您可以调用second()和third()。
function first(callback) {
setTimeout(function() {
$('#q').append('first <br>');
callback();
}, 1000);
}
function second() {
$('#q').append('second <br>');
}
function third() {
$('#q').append('third <br>');
}
first(function(){
second();
third();
});
回答by Rob M.
A few problems: Your firstfunction (and the rest of them, for that matter) are not returning promises, so you can't use done. If you were using promises, donewould seal the promise and not allow you to chain another donecall. For this setup, you would be better off nesting your function calls like:
一些问题:您的first函数(以及其他函数,就此而言)没有返回承诺,因此您不能使用done. 如果您正在使用承诺,done将密封承诺并且不允许您链接另一个done调用。对于这种设置,最好嵌套如下函数调用:
function first() {
setTimeout((function() {
$('#q').append('first <br>');
second();
}), 1000);
}
function second() {
$('#q').append('second <br>');
third();
}
function third() {
$('#q').append('third <br>');
}
回答by Deenadhayalan Manoharan
Try this..
尝试这个..
function first() {
setTimeout((function() {
$('#q').append('first <br>');
second();
third();
}), 1000);
}
function second() {
$('#q').append('second <br>');
}
function third() {
$('#q').append('third <br>');
}
first();
回答by Yangguang
try:
尝试:
function start() {
setTimeout((function () {
$.when(first()).done(second()).done(third());
}), 1000);
}
function first() {
$('#q').append('first <br>');
}
function second() {
$('#q').append('second <br>');
}
function third() {
$('#q').append('third <br>');
}
start();

