2012-12-10 29 views
15

我在这里非常努力地学习编写异步JavaScript。能否请您提供一个简单的JavaScript函数,它是异步的写在普通的JavaScript的一个实例(而不是如何使用Node.js或JQuery的)什么是异步JavaScript函数的简单示例?

+2

'setTimeout' ??? – Bergi

+1

事件处理程序。 –

+0

@SLaks阅读Bergi的答案。这基本上是我所指的。 – Ryan

回答

28

JavaScript本身是同步和单线程的。你不能写一个异步函数;纯JS没有计时API。并行线程不会产生副作用。

你可以做的是使用你的环境(Node.js的,的Webbrowser),允许您安排异步任务提供了一些API - 使用超时,AJAX功能,FileAPI,​​,nextTick,WebWorkers,DOM事件,等等。

使用setTimeout(由HTML Timing API提供)一个例子:

window.setTimeout(function() { 
    console.log("World"); 
}, 1000); 
console.log("Hello"); 

更新:由于ES6有承诺作为异步基本建成普通的JavaScript,所以你可以做

Promise.resolve("World").then(console.log); // then callbacks are always asynchronous 
console.log("Hello"); 

但是,在没有任何可以等待的情况下(比如超时),它们本身并没有真正的帮助。而且它们也不会改变线程模型的任何内容,所有的执行都是从头到尾完成的,没有任何事件干扰。

+1

好的答案,但是使用'bind'真的有必要吗?可能会混淆OP更多... – bfavaretto

+0

+1,非常真实; “异步”任务只是在执行队列中转移的任务。因此,(有时)使用'setTimeout(func,0)'的有用技巧。 ) – raina77ow

+0

@bfavaretto:不想重复Xeano的答案。现在改变以减少混淆:-) – Bergi

7

这是异步的:

setTimeout(function(){ 
    console.log('1'); 
}, 2000); 

console.log('2'); 

2将被写入到控制台之前1.因为setTimeout是异步的。

7

这里有一个很简单的例子:

for (var i = 0; i < 10; i++) { 
    window.setTimeout(function() { 
    console.log(i); 
    }, 2000); 
} 

你可能期望这些console.log()电话向您展示0, 1, 2等,在这个片段:

for (var i = 0; i < 10; i++) { 
    console.log(i); 
} 

但实际上只有10旨意是印!该函数传入setTimeout功能(作为其“回调”的说法)的理由将被调用for循环完成后 - 即,后i值设置为10

然而,你应该明白一件事情:所有的JavaScript在浏览器中执行单个线程;异步事件(例如鼠标点击和计时器)仅在执行队列中存在开放时才运行。 John Resig撰写的关于此主题的a brilliant article

+5

循环的问题是一个范围问题,并不是因为它的异步性质。如果他们的范围是正确的,循环将按预期工作。虽然这是对传递给'setTimout'的函数的一个很好的解释,执行_after_ for'循环 – Ian