javascript:异步操作 回调函数
另一篇讲解异步编程不错的文章:https://segmentfault.com/a/1190000002938132
第二篇:更加通俗易懂
单线程是JavaScript的一大特性。
JavaScript不像其他语言比如Java一样多线程,就不必去考虑线程同步的问题。
JavaScript是浏览器用来与用户进行交互、进行DOM操作的,这也使得了它必须是单线程这一特性。比如你去修改一个元素的DOM,同时又去删除这个元素,那么浏览器应该听谁的?
在JavaScript中任务有两种,一种是同步任务,一种是异步任务。
同步任务:各个任务按照文档定义的顺序一一推入"执行栈"中,当前一个任务执行完毕,才会开始执行下一个任务。
异步任务:各个任务推入"任务队列"中,只有在当前的所有同步任务执行完毕,才会将队列中的任务"出队"执行。(注:这里的异步任务并不一定是按照文档定义的顺序推入队列中)
//只有用户触发点击事件才会被推入队列中(如果点击时间小于定时器指定的时间,则先于定时器推入,否则反之)
document.querySelector("#box").onclick = function(){
console.log("click");
};
//第一个推入队列中
setTimeout(function(){
console.log("1");
},0);
//第三个推入队列中
setTimeout(function(){
console.log("2");
},1000);
//第二个推入队列中
setTimeout(function(){
console.log("3");
},0);
当然了,这时候你会疑惑"任务队列是什么?异步任务通常包括哪些?"
任务队列(event loop):你可理解为用于存放事件的队列,当执行一个异步任务时,就相当于执行任务的回调函数。
通常io(ajax获取服务器数据)、用户/浏览器自执行事件(onclick、onload、onkeyup等等)以及定时器(setTimeout、setInterval)都可以算作异步操作。
我所知道的有这些,如果有其它的事件是异步的,欢迎大大补充。
先来看一段代码来理解一下
console.log("1");
setTimeout(function(){
console.log("2");
},1000);
console.log("3");
setTimeout(function(){
console.log("4");
},0);
输出结果: 1->3->4->2.
分析:
1. 两个console.log()都是同步,按照文档的顺序将它们推入"执行栈"中。
2. 执行栈中的同步任务执行完毕。
3. 将两个异步任务(定时器)按照第二个参数(延迟执行的时间)顺序推入"任务队列"中。
4. 一一执行异步任务。
那么在来看你这段代码。
//同步code1
var t = true;
//异步code2
window.setTimeout(function (){
t = false;
},1000);
//同步code2
while (t){}
//同步code3
alert('end');
分析:
1. 先执行同步code1->同步code2。
2. 此时while(true){},进入死循环,以后的代码都不会执行。