setTimeout是用javascript做异步函数的好方法吗?

时间:2013-10-28 03:16:45

标签: javascript jquery

在网上搜索异步函数,我发现很多文章使用setTimeout来完成这项工作:

window.setTimeout(function() {
   console.log("second");
}, 0);
console.log("first");

输出:

first
second

这有效,但是最佳做法?

3 个答案:

答案 0 :(得分:64)

setTimeout(function(){...}, 0)只需将代码排队,即可在当前调用堆栈执行完毕后运行。这可以是useful for some things

所以是的,它是异步的,因为它打破了同步流,但实际上并不是在一个单独的线程上并发执行。如果您的目标是后台处理,请查看webworkers。还有一种方法可以使用iframe进行后台处理。

<强>更新

进一步澄清,并发/后台和异步之间存在差异。当代码是异步的时,这意味着它不是按顺序执行的。考虑:

var foo = 'poo';
setTimeout(function() {foo = 'bar'}, 100);
alert(foo);

值'poo'将被警告,因为代码没有按顺序执行。 'bar'值是异步分配的。如果在发生异步分配时需要提醒foo的值,请使用回调:

/* contrived example alert */
var foo = 'poo';
function setFoo(callback) {
  setTimeout(function(){
    foo = 'bar';
    callback();
  }, 100);
};
setFoo(function() {
  alert(foo);
});

所以是的,上面发生了一些异步现象,但这一切都发生在一个线程中,因此没有性能优势。

当操作需要很长时间时,最好在后台执行。在大多数语言中,这是通过在新线程或进程上执行操作来完成的。在(浏览器)javascript中,我们无法创建新线程,但可以使用webworkers或iframe。由于此代码在后台运行会破坏事物的顺序流,因此它是异步的。

TLDR :所有后台/并发代码都是异步发生的,但并非所有异步代码都同时发生。

另见Understanding Asynchronous Code in Layman's terms

答案 1 :(得分:1)

var foo = 'poo';
setTimeout(function() {foo = 'bar'}, 100);
alert(foo);

@ tybro0103答案的小修正,在执行'alert(foo)'时,值'poo'不会改变,因为代码没有按顺序执行。 “bar”值是异步分配的,只有在100毫秒后才会执行,届时将执行警报。

foo 的值保持不变,执行线路警报(foo)。并会在以后的时间改变。检查@ vishal-lia评论。

答案 2 :(得分:0)

默认情况下,每当JavaScript遇到异步函数时,它都是异步的,它将对该函数排队以便稍后使用。 但是,如果您想暂停js,可以使用promises 情况1:输出hello(将不等待setTimeout) https://jsfiddle.net/shashankgpt270/h0vr53qy/

//async 
function myFunction() {
let result1='hello'
//promise =new Promise((resolve,reject)=>{
setTimeout(function(){ 
resolve("done");
result1="done1";
}, 3000);
//});
 //result = await promise
 alert(result1);
}
myFunction();

情况2:输出done1(将等待setTimeout) https://jsfiddle.net/shashankgpt270/1o79fudt/

async function myFunction() {
let result1='hello'
promise =new Promise((resolve,reject)=>{
setTimeout(function(){ 
resolve("done");
result1="done1";
}, 3000);
});
 result = await promise
 alert(result1);
}
myFunction();