Promise
全局参数
- state
存储当前promise的状态 - value
存储回调函数的resolve或者reject的值 - handlers
store sucess & failure handlers attached by calling .then or .done
方法
底层函数:状态变迁,记录变迁状态并存储value
- fulfill
- reject
resolve:支持传递值或者promise对象进入,生成一个新的promise对象
- getThen
判断是否时一个promise对象,通过查看它是有then方法的function或者Object判定
成功返回then函数,失败返回null - doResolve
实现resolve方法,传入函数,resolve函数,reject函数参数,等待回调调用
这里resolve和reject函数作执行判定,不能重复调用
若是程序出错,直接reject返回 - resolve
判断传入参数:
若为promise对象则递归调用doResolve和resolve方法,直到promise嵌套完成(同步)
若为值,则调用fulfill或reject传出
从这里可以看出
new Promise((resolve, reject) => {
//该函数为同步
//直到resolve或者reject才是异步部分
})
//以下代码执行过程就不难理解了
//2 3 5 4 1
//第一个setTimeout会在下一个事件周期执行
//开始同步部分
//2->3->5
// 同步执行完成后开始下一个事件周期
//4
//延时执行的1
setTimeout(function() {
console.log(1)
}, 0);
new Promise(function executor(resolve) {
console.log(2);
for( var i=0 ; i<10000 ; i++ ) {
i == 9999 && resolve();
}
console.log(3);
}).then(function() {
console.log(4);
});
console.log(5);
这里的4->1的过程我还是有点晕。不过如果将setTimeout换为process.nextTick将会变成1->4
大概setTimeout有延时最小值,node的setTimeout这里需要再研究一下
请教了一下人,得到结论是这样V8优先级顺序
done根据promise的状态执行函数
保证异步实现
接收两个函数参数onFulfilled, onRejected
- PENDING
将传入参数hander存入handlers - FULFILLED
执行传入参数hander的onFulfilled方法 - REJECTED
执行传入参数hander的onRejected方法
then
调用主promise对象的done方法,传入两个函数参数,done方法根据目前状态执行对应方法。
then重新生成新的Promise对象返回。
这样相当于一个Promise对象通过执行回调将值传给它的下一个then,then方法调用回调得到值并构建一个新的Promise对象。相当于每个new Promise().then()也是一个new Promise()。
catch
和then方法相同,不过只接收onRejected方法
race和all方法
参照Promise原理分析二
Events
Node.js 中 Eventemitter 的 emit 是同步的.
这样会崩溃
const EventEmitter = require('events');
let emitter = new EventEmitter();
emitter.on('myEvent', () => {
console.log('hi');
emitter.emit('myEvent');
});
emitter.emit('myEvent');
这样没事
const EventEmitter = require('events');
let emitter = new EventEmitter();
emitter.on('myEvent', function sth () {
emitter.on('myEvent', sth);
console.log('hi');
});
emitter.emit('myEvent');
为啥?
Timers
之前有一篇文章分析过了,这里不再阐述。可以参照setImmediate vs nextTick vs setTimeout(fn, 0)
并行/并发
直接引用饿了么的说明
并行 (Parallel) 与并发 (Concurrent) 是两个很常见的概念.
可以看 Erlang 作者 Joe Armstrong 的博客 (Concurrent and Parallel)
并发 (Concurrent) = 2 队列对应 1 咖啡机.
并行 (Parallel) = 2 队列对应 2 咖啡机.
Node.js 通过事件循环来挨个抽取实践队列中的一个个 Task 执行, 从而避免了传统的多线程情况下 2个队列对应 1个咖啡机
的时候上线文切换以及资源争抢/同步的问题, 所以获得了高并发的成就.
至于在 node 中并行, 你可以通过 cluster 来再添加一个咖啡机.
传送门