单线程
单线程,但是js的引擎不只有一个线程,还可以其他任务线程;
事件驱动:触发事件就执行。
采用事件循环机制,先将主线的任务(同步)执行完毕,在执行队列任务(异步)。不断这样循环执行。
node非阻塞I/O模型:将循环查看是否有任务队列(其他线程)中是否有任务等待;异步I/O。
同步和异步任务
同步任务:主线程将代码一步步执行下来,需要等待。
异步任务:引擎会将异步代码放在另任务队列中,等待同步的代码执行完毕,才进行异步代码的执行。异步任务又分为:
macrotasks(宏任务):
- setTimeout
- setInterval
- setImmediate
- requestAnimationFrame
- I/O
- UI rendering
microtasks(微任务):
- process.nextTick
- Promises
- Object.observe
- MutationObserver
☆microtasks先于macrotasks执行
例如
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
},0);
Promise.resolve()
.then(function() { console.log('promise1'); })
.then(function() { console.log('promise2'); });
console.log('script end');
链接:https://www.jianshu.com/p/d3e...
异步实现的几种模式
通过回调形成异步,
就是回调函数不需要等待主函数的结果才会执行,不会影响主函数后面的代码。列如ajax就是通过回调形成的异步,
eg:
function f1(){
console.log(1)
}
function f2(){
console.log(2)
}
f1()
f2()
//上述代码是同步的,所以f2需要f1执行完才会执行。
//改成异步,就是将f2改成f1的回调。
function f1(){
console.log(1)
}
function f2(){
console.log(2)
}
f1(f2);
//f1(f2())
通过事件驱动
事件驱动机制,就是绑定一个事件,触发该事件后才执行。列如,js的addEventListener、jquery的on()方法、定时器、
//js
window.addEventListener("click",function(){
alert(1111)
})
window.click();
//jquery
f1.on("success",f2)
function f1(){
ajax(url,function(){
f1.trigger("success")
})
}
//jquery
f1.on("done",f2);
function f1(){
setTimeout(function(){
f1.triggle("success");
},1000)
}
//定时器
var num=1;
setTimeout(function f2(){
num++;
console.log(num);
})
console.log(num);
结论:可以绑定多个监听事件;形成多个回调,利于模块化。但是由于事件驱动,所以很难看出主流程。
发布/订阅
事件完全可以理解为“信号”,如果存在一个“信号中心”,某个任务执行完成,就向事件中心”发布“。其他任务则向”信号中心“询问情况。从而知道什么时候自己可以开始。
//利用jquery的插件实现
//首先,f2向消息中心订阅success事件
jQuery.subscribe('success',f2);
//对f1进行改写:
function f1(){
ajax(url,() => {
//todo
jQuery.publish('success');//当f1执行完毕后,向消息中心jQuery发布success事件,从而执行f2函数
})
}
//f2执行完毕后,可以取消订阅
jQuery.unsubscribe('success',f2)
Promise
es6语法
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。