By : 司嘉年(moke)
(by:阮一峰的网络日志,再谈Event Loop)
主线程从“任务队列”中读取事件,不断循环
(by:阮一峰的网络日志,再谈Event Loop)
macro-tasks :script(整体代码),setTimeout,setInterval,setImmediate,I/O,UI
micro-tasks :process.nextTick,Promises,Object.observe,MutationObserver(html5新特性)
在一个事件循环里,
这两个队列会分两步执行,
第一步会固定地执行一个(且仅一个)Macrotask任务,
第二步会执行整个Microtask队列中的所有任务。
用代码来感受
Macrotasks : 代表一些离散的独立的工作,task结束后,浏览器继续其他工作如页面重渲染和垃圾回收等
Microtasks : 更新完成应用程序状态的较小任务,在UI重渲染之前执行某些任务,避免不必要的UI渲染
Vue 中 MutationObserver
var counter = 1
var observer = new MutationObserver(nextTickHandler)
var textNode = document.createTextNode(String(counter))
observer.observe(textNode, {
characterData: true
})
timerFunc = () => {
counter = (counter + 1) % 2
textNode.data = String(counter)
}
JS异步发展
Callback
getData(function(a){
getMoreData(a, function(b){
getMoreData(b, function(c){
getMoreData(c, function(d){
getMoreData(d, function(e){
...
});
});
});
});
});
Promise
// 没有 promise
a(getResultFromA, (aResult, err) => {
if (!err) {
b(getResultFromB, (bResult, err) => {
if (!err) {
c(getResultFromC, (cResult, err) => {
if (!err) {
// do something
} else {
throw err
}
})
} else {
throw err
}
})
} else {
throw err
}
})
// 用了 promise 后
new promise((resolve, reject) => {
a(getResultFromA, (aResult, err) => {
if (!err) resolve(aResult) else reject(err)
})
})
.then(data => {
return new Promise((resolve, reject) => {
b(getResultFromB, (bResult, err) => {
if (!err) resolve(bResult) else reject(err)
})
}
})
.then(data => {
return new Promise((resolve, reject) => {
c(getResultFromC, (cResult, err) => {
if (!err) resolve(cResult) else reject(err)
})
}
})
.then(data => {
// do something
})
.catch(err => {
throw err
})
Generator
// 定义
var fetch = require('node-fetch');
function* gen(){
var url = 'https://api.github.com/users/github';
var result = yield fetch(url);
console.log(result.bio);
}
// 使用
var g = gen();
var result = g.next();
result.value.then(function(data){
return data.json();
}).then(function(data){
g.next(data);
});
Async
Rxjs(流Stream)
Reactive Extensions for JavaScript
观察者+迭代器模式
Observables与Observer
Thanks
参考:ECMAScript 6 入门(阮一峰)
最后谈一次 JavaScript 异步编程(brambles)
Tasks, microtasks,
queues and schedules What the heck is the event loop anyway?
Concurrency model and Event Loop Macrotasks and Microtasks
......