js的流程控制老大难问题就是异步回调。
一个流程过程,往往会出现回调地狱,这个回调异步控制就被提上研究得议程。
目前有实现的回调流程有以下几种
- 回调函数实现
- 事件监听
- 发布订阅
- Promise/A+ 和生成器函数
- async/await
回调函数实现
fs.readFile((err,data)=>{
if(err){
console.err(err)
}else{
console.log(data);
}
})
事件发布订阅
使用node 模块EventEmitter 注册事件在完成后emit发射事件
let Promise = require('promise')
let p1 = new Promise((resolve,reject)=>{
setTimeout(function () {
resolve('p1完成')
},100)
})
let p2 = new Promise((resolve,reject)=>{
setTimeout(function () {
reject('p2失败')
},200)
})
p1.then(function (data) {
eve.emit('ready','p1成功',data)
},function (data) {
eve.emit('ready','p1失败',data)
})
p2.then(function (data) {
eve.emit('ready','p2成功',data)
},function (data) {
eve.emit('ready','p2失败',data)
})
//事件订阅
let EventEmitter = require('events');
let eve = new EventEmitter();
let html = {}
eve.on('ready',function (key,value) {
html[key] = value
if(Object.keys(html).length == 2){
console.log(html)
}
})
哨兵变量
let Promise = require('promise')
//哨兵变量
function render(length,cb) {
let html = {}
return function (key,value) {
html[key] = value
if(Object.keys(html).length == length){
cb(html)
}
}
}
let p1 = new Promise((resolve,reject)=>{
setTimeout(function () {
resolve('p1完成')
},100)
})
let p2 = new Promise((resolve,reject)=>{
setTimeout(function () {
reject('p2失败')
},200)
})
let done = render(2,function (data) {
console.log(data)
})
p1.then(function (data) {
done('p1成功',data)
},function (data) {
done('p1失败',data)
})
p2.then(function (data) {
done('p2成功',data)
},function (data) {
done('p2失败',data)
})
yield
let fs = require('fs')
function *gen() {
console.log(1)
let b = yield p1()
console.log(2)
return b
}
function p1(){
fs.read
}
let it = gen()
let r1 = it.next()
console.log(r1);
let r2 = it.next()
console.log(r2);
let r3 = it.next()
console.log(r3);
co
let fs = require('fs');
function readFile(filename) {
return new Promise(function (resolve, reject) {
fs.readFile(filename, function (err, data) {
if (err)
reject(err);
else
resolve(data);
})
})
}
function *read() {
let template = yield readFile('./template.txt');
let data = yield readFile('./data.txt');
return template + '+' + data;
}
co(read).then(function (data) {
console.log(data);
}, function (err) {
console.log(err);
});
Async/ await
let fs = require('fs');
function readFile(filename) {
return new Promise(function (resolve, reject) {
fs.readFile(filename, 'utf8', function (err, data) {
if (err)
reject(err);
else
resolve(data);
})
})
}
async function read() {
let template = await readFile('./template.txt');
let data = await readFile('./data.txt');
return template + '+' + data;
}
let result = read();
result.then(data=>console.log(data));