function f1(callback){
callback();
}
function f2(callback){
callback();
}
function f3(callback){
callback();
}
f1(f2(f3))
复制代码
这种方式实现异步编程优势是思路清晰,以串行的思考方式进行编程,缺点是造成回调地狱,过多的回调嵌套使得代码变得难以理解拆分和维护。es6
let dep = {
list: [],
on: function (fn) {
list.push(fn);
},
emit: function () {
this.list.forEach(event => {
typeof event === 'function' ? event() : null;
})
}
};
复制代码
上面就是简易版的发布订阅模式:发布者存在一个数组list用于登记订阅者即异步执行的函数,等到必定条件下执行emit,订阅的异步函数都会执行。这就比如发布者售楼中心的拥有一个登记册,里面登记须要买房的全部订阅者,有的订阅者登记的是电话通知,有的订阅者登记的邮件通知,等到楼盘信息变化时会主动给每一个订阅者执行相应的操做(执行对应的函数)编程
promise的核心原理其实就是发布订阅模式,经过两个队列来缓存成功的回调(onResolve)和失败的回调(onReject)。若是还不熟悉promise用法的朋友,请参考Es6入门之promise对象,下面来分析promise的特色。数组
下面针对这些特色来实现promise:promise
function Promise (executor){
function resolve(value){}
function reject(value){}
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
}
var promise = new Promise((resolve,reject)=>{
console.log('start');
})
复制代码
function Promise (executor) {
var self = this;//resolve和reject中的this指向不是promise实例,须要用self缓存
self.state = 'padding';
self.value = '';//缓存成功回调onfulfilled的参数
self.reson = '';//缓存失败回调onrejected的参数
self.onResolved = []; // 专门存放成功的回调onfulfilled的集合
self.onRejected = []; // 专门存放失败的回调onrejected的集合
function resolve (value) {
if(self.state==='padding'){
self.state==='resolved';
self.value=value;
self.onResolved.forEach(fn=>fn())
}
}
function reject (reason) {
self.state = 'rejected';
self.value = reason;
self.onRejected.forEach(fn=>fn())
}
try{
executor(resolve,reject)
}catch(e){
reject(e)
}
}
复制代码
Promise.prototype.then=function (onfulfilled,onrejected) {
var self=this;
if(this.state==='resolved'){
onfulfilled(self.value)
}
if(this.state==='rejected'){
onrejected(self.value)
}
if(this.state==='padding'){
this.onResolved.push(function () {
onfulfilled(self.value)
})
}
}
复制代码
以上只是实现了promise的基本功能,可是还缺乏then的链式调用,then函数参数onfulfilled,onrejected缺省处理,链式调用返回值多种状况的处理,下面分析then方法的特色:缓存
Promise.prototype.then=function (onfulfilled,onrejected) {
onfulfilled = typeof onfulfilled == 'function' ? onfulfilled : val => val;//onfulfilled缺省处理
onrejected = typeof onrejected === 'function' ? onrejected : err => {throw err;};//onrejected缺省处理
var self=this,promise2=new Promise(function(resolve,reject){//返回一个promise
if(this.state==='resolved'){
try{
onfulfilled(self.value);//里面会执行resolve
}catch(e){
reject(e);
}
}
if(this.state==='rejected'){
try{
onrejected(self.value);
}catch(e){
reject(e);
}
}
if(this.state==='padding'){//将执行过程缓存
self.onResolved.push(function () {
try{
onfulfilled(self.value);
}catch(e){
reject(e)
}
});
self.onRejected.push(function () {
try{
onrejected(self.value);
}catch(e){
reject(e)
}
})
}
})
return promise2;
}
复制代码
Promise.prototype.then=function (onfulfilled,onrejected) {
onfulfilled = typeof onfulfilled == 'function' ? onfulfilled : val => val;
onrejected = typeof onrejected === 'function' ? onrejected : err => {throw err;};
var self=this,
res=null,//用来缓存onfulfilled或onrejected的返回值
promise2=new Promise(function(resolve,reject){
if(this.state==='resolved'){
try{
res = onfulfilled(self.value);//获得onfulfilled的返回值
resolvePromise(promise2,res,resolve,reject);//返回值的处理函数
}catch(e){
reject(e);
}
}
if(this.state==='rejected'){
try{
res = onrejected(self.value);//获得onrejected的返回值
resolvePromise(promise2,res,resolve,reject);
}catch(e){
reject(e);
}
}
if(this.state==='padding'){
self.onResolved.push(function () {
try{
res = onfulfilled(self.value);
resolvePromise(promise2,res,resolve,reject);
}catch(e){
reject(e)
}
});
self.onRejected.push(function () {
try{
res = onrejected(self.value);
resolvePromise(promise2,res,resolve,reject);
}catch(e){
reject(e)
}
})
}
})
return promise2;
}
function resolvePromise(promise,res,resolve,reject) {
if(promise===res){//防止循环引用
return reject(new TypeError('循环引用'))
}
let called;//防止重复执行
if(res!==null&&(typeof res==='function'||typeof res ==='object')){
try {//防止promise执行报错
let then=res.then;//判断是否promise就判断是否存在then方法
if(typeof then ==='function'){//若是返回的是promise,只须要在返回的promise的then方法中下一步须要执行的函数
then.call(res,(res2)=>{
if (called) return;
called = true;
resolvePromise(promise,res2,resolve,reject);//若是是promise继续递归执行,直到不是promise,依次执行外层的resolve,让promise状态改变
},)
}else{//若是不是promise,有多是undefine、onfulfilled或onrejected的返回的普通值,就直接将这个值返回,将外层的promise状态改变
if (called) return;
called = true;
resolve(then)
}
}catch(e){
if (called) return;
called = true;
reject(e)
}
}else{
resolve(res)
}
};
复制代码
console.log(1);
var promise=new Promise(function(resolve,reject){
resolve('a');
})
promise.then(function(value){
console.log(value)
})
console.log(2);
// 1 2 'a'
复制代码
//因为promise有内部的机制实现微任务,因此这里使用setTimeout代替
Promise.prototype.then=function (onfulfilled,onrejected) {
onfulfilled = typeof onfulfilled == 'function' ? onfulfilled : val => val;
onrejected = typeof onrejected === 'function' ? onrejected : err => {throw err;};
var self=this,
res=null,
promise2=new Promise(function(resolve,reject){
if(this.state==='resolved'){
setTimeout(()=>{
try{
res = onfulfilled(self.value);
resolvePromise(promise2,res,resolve,reject);
}catch(e){
reject(e);
}
})
}
if(this.state==='rejected'){
setTimeout(()=>{
try{
res = onrejected(self.value);
resolvePromise(promise2,res,resolve,reject);
}catch(e){
reject(e);
}
})
}
if(this.state==='padding'){
self.onResolved.push(function () {
setTimeout(()=>{
try{
res = onfulfilled(self.value);
resolvePromise(promise2,res,resolve,reject);
}catch(e){
reject(e);
}
})
});
self.onRejected.push(function () {
setTimeout(()=>{
try{
res = onrejected(self.value);
resolvePromise(promise2,res,resolve,reject);
}catch(e){
reject(e);
}
})
})
}
})
return promise2;
}
复制代码
Promise.prototype.catch = function (onrejected) {
return this.then(null, onrejected)
};
复制代码
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
};
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
resolve(value);
})
};
复制代码
//在每一个promise的回调中添加一个判断函数processData(就是在当前的promise.then中添加),每一个promise状态改变后让index++,直到和promises的个数相等就执行回调
Promise.all=function (promises) {
return new Promise((resolve,reject)=>{
let results=[],i=0;
for(let i=0;i<promises.length;i++){
let p=promises[i];
p.then((data)=>{
processData(i,data)
},reject)
}
function processData (index,data) {
results[index]=data;
if(++i==promises.length){
resolve(results)
}
}
})
};
//在每一个promise的回调中添加一个resolve(就是在当前的promise.then中添加),有一个状态改变,就让race的状态改变
Promise.race=function (promises) {
return new promises((resolve,reject)=>{
for(let i=0;i<promises.length;i++){
let p=promises[i];
p.then(resolve,reject)
}
})
};
复制代码
Generator函数能够经过yield暂停执行和next恢复执行,因此能够封装一个函数来自动执行next函数而使Generator完成异步任务。bash
let fs = require('mz/fs');
function * read() {
let age = yield fs.readFile('./name.txt','utf8');
let adress = yield fs.readFile(age,'utf8');
let r = yield fs.readFile(adress,'utf8');
return r;
}
function co(it) {//it为一个generator对象
//返回一个promise而且执行generator对象的next
return new Promise((resolve,reject)=>{
function next(data) {
//获取前一个异步函数的返回值,其必须为promise
let { value, done } = it.next(data);
if(!done){
//返回promise的then方法中添加generator的next
//前一个异步函数执行成功会使返回的promise成resolved
//而后执行generator的next,递归依次类推
value.then(data=>{
next(data)
}, reject);
}else{
resolve(value);
}
}
next();
})
}
co(read()).then(data=>{
console.log(data);
},err=>{
console.log(err);
});
复制代码
async+awit等于generator+co,而co中实现generator自动化是基于Promise,因此awit会使用new Promise形式。异步
若是以上有任何错误之处,但愿提出并请指正,若是对promise使用还不清楚的朋友,请参考Es6入门之promise对象,本文参考:async