单线程

单线程,但是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语法

异步的流程控制

串行

并行

串,并行结合


用户bPbuFxB
51 声望4 粉丝