//11、promise2和x引用的同一个变量
const Promise = require('./promise');
let p = new Promise((resolve,reject)=>{
resolve(1);
});
let promise2 = p.then(data=>{
}).then(data=>{
});
//promise执行then两次之后的promise
//这两种写法不一致(上与下)
//promise执行then一次之后的promise
let promise2 = p.then(data=>{
});
promise2.then(data=>{
});
/***********************************/
let p = new Promise((resolve,reject)=>{
resolve(1);
});
let promise2 = p.then(data=>{
return promise2; //promise2等待promise2完成(死循环)
});
promise2.then(()=>{
},err=>{
console.log(err);//TypeError:Chaining cycle detected for Promise #<Promise>
})
/***************************************/
//promise.js
const RESOLVED = 'RESOLVED';//成功
const REJECTED = 'REJECTED';//失败
const PENDING = 'PENDING';//等待态
//resolvePromise 所有的promise都要坚持 bluebird q es6-promise
const resolvePromise=(promise2,x,resolve,reject)=>{
//1、循环引用 自己等待自己完成 错误的实现
if(promise2 === x){ //用一个错误类型 结束掉promise
return reject(new TypeError('chaining cycle detected for promise #<Promise>'));
}
//后续的条件要严格判断,保证代码能和别的库一起使用
let called;
if ((typeof x=== 'object' && x != null) || typeof x === 'function') //有可能是一个promise
{
//要继续判断
try{
let then = x.then;
if(typeof then === 'function')//只能认为是一个promise了
{
//不要写成x.then,直接then.call就可以了,因为x.then会再次取值
then.call(x, y=>{ //根据promise的状态决定是成功还是失败
if(called)return; //防止别人的promise影响
called = true;
//resolve(y);
resolvePromise(promise2,y,resolve,reject);//递归解析的过程
},err=>{
if(called)return;
called = true;
reject(err);
});
}
else //{then:'23'}
{
resolve(x);
}
}catch(e){ //防止失败了再次进入成功
if(called)return;
called = true;
reject(e);//取值出错
}
}
else
{
resolve(x);
}
};
class Promise{
constructor(executor){
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks=[];//专门用来存放成功的回调
this.onRejectedCallbacks=[];//专门用来存放失败的回调
let resolve = (value)=>{
if(this.status === PENDING){
this.value = value;
this.status = RESOLVED;
this.onResolvedCallbacks.forEach(fn=>fn());
}
}
let reject = (reason)=>{
if(this.status === PENDING){
this.reason = reason;
this.status = REJECTED;
this.onRejectedCallbacks.forEach(fn=>fn());
}
}
try{
executor(resolve,reject);//立即执行
}catch(e){
reject(e);
}
}
//1、promise成功和失败的回调的返回值,可以传递到外层的下一个then
//2、如果返回的是普通值的话(传递到下一次的成功中,不是错误不是promise就是普通值),可能还要promise的情况
//(会采用promise的状态,决定走下一次的成功还是失败)、出错的情况(一定会走到下一次的失败)
//3、错误处理 如果离自己最近的then没有错误处理(没有写错误函数)会向下找
//4、每次执行完promise.then方法后返回的都是一个“新的promise”(promise一旦成功或者失败就不能修改状态)
then(onFulfilled,onRejected){
let promise2 = new Promise((resolve,reject)=>{ //为了实现链式调用
if(this.status === RESOLVED){
setTimeout(()=>{
try{
let x = onFulfilled(this.value);
//x可能是一个promise,加上setTimeout的原因是等待promise2执行完毕,获取到promise2
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
}
if(this.status === REJECTED){
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
//todo...
setTimeout(()=>{
try{
let x = onFulfilled(this.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
});
this.onRejectedCallbacks.push(()=>{
//todo...
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
});
}
});
return promise2;
}
}
module.exports = Promise;
//12、根据x值来判断是成功还是失败
//别人定义的promise
Object.defineProperty(x,'then',{
get(){
throw new Error();
}
});
const Promise = require('./promise');
let p = new Promise((resolve,reject)=>{
resolve(1);
});
let promise2= p.then(data=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('错误');
},1000);
})
});
promise2.then((data)=>{
console.log('成功',data);
},err=>{
console.log('fail',err); //TypeError:Chaining cycle detected for promise #<Promise>
});
//成功 错误
//13、promise的状态更改问题
const Promise = require('./promise');
let p = new Promise((resolve,reject)=>{
resolve(1);
});
let promise2 = p.then(data=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(2000);
},1000);
}))
},1000);
})
});
promise2.then((data)=>{
console.log('成功',data);
},err=>{
console.log('fail',err);
});
//成功 2000
//14、规范测试
const Promise=require('./promise');
let p = new Promise((resolve,reject)=>{
resolve(1);
//reject(1);
});
p.then().then().then(data=>{
console.log(data);
},err=>{
console.log(err,'err');
});
/*****************************/
//promise.js
const RESOLVED = 'RESOLVED';//成功
const REJECTED = 'REJECTED';//失败
const PENDING = 'PENDING';//等待态
//resolvePromise 所有的promise都要坚持 bluebird q es6-promise
const resolvePromise=(promise2,x,resolve,reject)=>{
//1、循环引用 自己等待自己完成 错误的实现
if(promise2 === x){ //用一个错误类型 结束掉promise
return reject(new TypeError('chaining cycle detected for promise #<Promise>'));
}
//后续的条件要严格判断,保证代码能和别的库一起使用
let called;
if ((typeof x=== 'object' && x != null) || typeof x === 'function') //有可能是一个promise
{
//要继续判断
try{
let then = x.then;
if(typeof then === 'function')//只能认为是一个promise了
{
//不要写成x.then,直接then.call就可以了,因为x.then会再次取值
then.call(x, y=>{ //根据promise的状态决定是成功还是失败
if(called)return; //防止别人的promise影响
called = true;
//resolve(y);
resolvePromise(promise2,y,resolve,reject);//递归解析的过程
},err=>{
if(called)return;
called = true;
reject(err);
});
}
else //{then:'23'}
{
resolve(x);
}
}catch(e){ //防止失败了再次进入成功
if(called)return;
called = true;
reject(e);//取值出错
}
}
else
{
resolve(x);
}
};
class Promise{
constructor(executor){
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks=[];//专门用来存放成功的回调
this.onRejectedCallbacks=[];//专门用来存放失败的回调
let resolve = (value)=>{
if(this.status === PENDING){
this.value = value;
this.status = RESOLVED;
this.onResolvedCallbacks.forEach(fn=>fn());
}
}
let reject = (reason)=>{
if(this.status === PENDING){
this.reason = reason;
this.status = REJECTED;
this.onRejectedCallbacks.forEach(fn=>fn());
}
}
try{
executor(resolve,reject);//立即执行
}catch(e){
reject(e);
}
}
//1、promise成功和失败的回调的返回值,可以传递到外层的下一个then
//2、如果返回的是普通值的话(传递到下一次的成功中,不是错误不是promise就是普通值),可能还要promise的情况
//(会采用promise的状态,决定走下一次的成功还是失败)、出错的情况(一定会走到下一次的失败)
//3、错误处理 如果离自己最近的then没有错误处理(没有写错误函数)会向下找
//4、每次执行完promise.then方法后返回的都是一个“新的promise”(promise一旦成功或者失败就不能修改状态)
then(onFulfilled,onRejected){
onFulfilled = typeof onFulfilled === 'function'?onFulfilled:v=>v;
onRejected = typeof onRejected === 'function'?onRejected:err=>{throw err};
let promise2 = new Promise((resolve,reject)=>{ //为了实现链式调用
if(this.status === RESOLVED){
setTimeout(()=>{
try{
let x = onFulfilled(this.value);
//x可能是一个promise,加上setTimeout的原因是等待promise2执行完毕,获取到promise2
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
}
if(this.status === REJECTED){
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
//todo...
setTimeout(()=>{
try{
let x = onFulfilled(this.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
});
this.onRejectedCallbacks.push(()=>{
//todo...
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
});
}
});
return promise2;
}
}
//promise测试
//promise的延迟对象
Promise.defer=Promise.deferred = function(){
let dfd ={};
dfd.promise = new Promise((resolve,reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
module.exports = Promise;
//测试命令
//npm install promises-aplus-tests -g
//promises-aplus-tests promise.js
//15、延迟对象的作用(没有测试通过)
const fs = require('fs');
const Promise = require('./promise');
let p = new Promise((resolve,reject)=>{
function read(filename){
let dfd = Promise.defer();
fs.readFile(filename,'utf8',(err,data)=>{
if(err)dfd.reject(err);
dfd.resolve(data);
});
return dfd.promise;
}
read('./name.txt').then((data)=>{
return read(data);
}).then((data)=>{
console.log(data);
});
//16、catch方法的实现
const fs = require('fs');
const Promise = require('./promise');
new Promise((resolve,reject)=>{
reject(1);
}).then((data)=>{
console.log(data);
}).catch(err=>{
console.log(err);
});
//用then实现
const fs = require('fs');
const Promise = require('./promise');
new Promise((resolve,reject)=>{
reject(1);
}).then((data)=>{
console.log(data);
}).then(null,err=>{
console.log(err,'------');
});
/***************************/
//promise.js
const RESOLVED = 'RESOLVED';//成功
const REJECTED = 'REJECTED';//失败
const PENDING = 'PENDING';//等待态
//resolvePromise 所有的promise都要坚持 bluebird q es6-promise
const resolvePromise=(promise2,x,resolve,reject)=>{
//1、循环引用 自己等待自己完成 错误的实现
if(promise2 === x){ //用一个错误类型 结束掉promise
return reject(new TypeError('chaining cycle detected for promise #<Promise>'));
}
//后续的条件要严格判断,保证代码能和别的库一起使用
let called;
if ((typeof x=== 'object' && x != null) || typeof x === 'function') //有可能是一个promise
{
//要继续判断
try{
let then = x.then;
if(typeof then === 'function')//只能认为是一个promise了
{
//不要写成x.then,直接then.call就可以了,因为x.then会再次取值
then.call(x, y=>{ //根据promise的状态决定是成功还是失败
if(called)return; //防止别人的promise影响
called = true;
//resolve(y);
resolvePromise(promise2,y,resolve,reject);//递归解析的过程
},err=>{
if(called)return;
called = true;
reject(err);
});
}
else //{then:'23'}
{
resolve(x);
}
}catch(e){ //防止失败了再次进入成功
if(called)return;
called = true;
reject(e);//取值出错
}
}
else
{
resolve(x);
}
};
class Promise{
constructor(executor){
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks=[];//专门用来存放成功的回调
this.onRejectedCallbacks=[];//专门用来存放失败的回调
let resolve = (value)=>{
if(this.status === PENDING){
this.value = value;
this.status = RESOLVED;
this.onResolvedCallbacks.forEach(fn=>fn());
}
}
let reject = (reason)=>{
if(this.status === PENDING){
this.reason = reason;
this.status = REJECTED;
this.onRejectedCallbacks.forEach(fn=>fn());
}
}
try{
executor(resolve,reject);//立即执行
}catch(e){
reject(e);
}
}
then(onFulfilled,onRejected){
onFulfilled = typeof onFulfilled === 'function'?onFulfilled:v=>v;
onRejected = typeof onRejected === 'function'?onRejected:err=>{throw err};
let promise2 = new Promise((resolve,reject)=>{ //为了实现链式调用
if(this.status === RESOLVED){
setTimeout(()=>{
try{
let x = onFulfilled(this.value);
//x可能是一个promise,加上setTimeout的原因是等待promise2执行完毕,获取到promise2
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
}
if(this.status === REJECTED){
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
//todo...
setTimeout(()=>{
try{
let x = onFulfilled(this.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
});
this.onRejectedCallbacks.push(()=>{
//todo...
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
});
}
});
return promise2;
}
catch(errCallback)
{
return this.then(null,errCallback);
}
static resolve(data){
return new Promise((resolve,reject)=>{
resolve(data);
})
}
static reject(reason){
return new Promise((resolve,reject)=>{
reject(reason);
})
}
}
//promise测试
//promise的延迟对象
Promise.defer=Promise.deferred = function(){
let dfd ={};
dfd.promise = new Promise((resolve,reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
module.exports = Promise;
//17、resolve和reject方法区别
//Promise.resolve();//快速创建一个成功的promise
//Promise.reject();快速的创建一个失败的promise
//区别在于resolve会等待里面的promise执行完毕,reject不会有等待效果
new Promise((resolve,reject)=>{
resolve(111);
}).then(data=>{
console.log(data);
};
Promise.resolve(new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok');
},1000);
})).then(data=>{
console.log(data);
});
/***************************/
//promise.js
const RESOLVED = 'RESOLVED';//成功
const REJECTED = 'REJECTED';//失败
const PENDING = 'PENDING';//等待态
//resolvePromise 所有的promise都要坚持 bluebird q es6-promise
const resolvePromise=(promise2,x,resolve,reject)=>{
//1、循环引用 自己等待自己完成 错误的实现
if(promise2 === x){ //用一个错误类型 结束掉promise
return reject(new TypeError('chaining cycle detected for promise #<Promise>'));
}
//后续的条件要严格判断,保证代码能和别的库一起使用
let called;
if ((typeof x=== 'object' && x != null) || typeof x === 'function') //有可能是一个promise
{
//要继续判断
try{
let then = x.then;
if(typeof then === 'function')//只能认为是一个promise了
{
//不要写成x.then,直接then.call就可以了,因为x.then会再次取值
then.call(x, y=>{ //根据promise的状态决定是成功还是失败
if(called)return; //防止别人的promise影响
called = true;
//resolve(y);
resolvePromise(promise2,y,resolve,reject);//递归解析的过程
},err=>{
if(called)return;
called = true;
reject(err);
});
}
else //{then:'23'}
{
resolve(x);
}
}catch(e){ //防止失败了再次进入成功
if(called)return;
called = true;
reject(e);//取值出错
}
}
else
{
resolve(x);
}
};
class Promise{
constructor(executor){
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks=[];//专门用来存放成功的回调
this.onRejectedCallbacks=[];//专门用来存放失败的回调
let resolve = (value)=>{
if(value instanceof Promise)
{
return value.then(resolve,reject);//递归解析resolve中的参数,直到这个值是普通值
}
if(this.status === PENDING){
this.value = value;
this.status = RESOLVED;
this.onResolvedCallbacks.forEach(fn=>fn());
}
}
let reject = (reason)=>{
if(this.status === PENDING){
this.reason = reason;
this.status = REJECTED;
this.onRejectedCallbacks.forEach(fn=>fn());
}
}
try{
executor(resolve,reject);//立即执行
}catch(e){
reject(e);
}
}
then(onFulfilled,onRejected){
onFulfilled = typeof onFulfilled === 'function'?onFulfilled:v=>v;
onRejected = typeof onRejected === 'function'?onRejected:err=>{throw err};
let promise2 = new Promise((resolve,reject)=>{ //为了实现链式调用
if(this.status === RESOLVED){
setTimeout(()=>{
try{
let x = onFulfilled(this.value);
//x可能是一个promise,加上setTimeout的原因是等待promise2执行完毕,获取到promise2
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
}
if(this.status === REJECTED){
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
//todo...
setTimeout(()=>{
try{
let x = onFulfilled(this.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
});
this.onRejectedCallbacks.push(()=>{
//todo...
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0);
});
}
});
return promise2;
}
catch(errCallback)
{
return this.then(null,errCallback);
}
static resolve(data){
return new Promise((resolve,reject)=>{
resolve(data);
})
}
static reject(reason){
return new Promise((resolve,reject)=>{
reject(reason);
})
}
}
//promise测试
//promise的延迟对象
Promise.defer=Promise.deferred = function(){
let dfd ={};
dfd.promise = new Promise((resolve,reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
module.exports = Promise;
//18、finally的实现原理
//finally:es10的语法
Promise.resolve().finally(()=>{
console.log('finally');
});
//finally表示不是最终的意思而是无论如何都会执行的意思
Promise.resolve(123).finally(()=>{
console.log('finally');
});
Promise.reject(123).finally(()=>{
console.log('finally');
}).catch(err=>{
console.log(err);
});
//finally 123
Promise.resolve(123).finally(()=>{
console.log('finally');
}).then(data=>{
console.log(data,'success');
}).catch(err=>{
console.log(err,'error')
});
//finally 123 'success'
//如果返回一个promise,会等待这个promise也执行完毕,(如果是失败的promise,会用他的失败原因传给下一个人)
Promise.prototype.finally = function(callback){
return this.then((value)=>{
return Promise.resolve(callback()).then(()=>value);
},(reason)=>{
return Promise.resolve(callback()).then(()=>{throw reason});
});
}
Promise.resolve(123).finally(()=>{
console.log('finally');
return new Promise((resolve,reject)=>{
setTimeout(()=>{
//resolve('ok');
reject('ok');
},3000);
})
}).then(data=>{
console.log(data,'success');
}).catch(err=>{
console.log(err,'error');
});