//6、简单的promise
//promise的特点以及概念
//https://promisesaplus.com/ promisea+规范,都通过这个规范来实现的
//promise es6内部已经实现了 ie不支持promise,需要polyfill es6-promise
//promise为什么会产生解决异步问题
//1、多个异步请求并发(希望同步最终的结果) Promise.all
//2、链式异步请求的问题 上一个人的输出是下一个人的输入 Promise的链式调用可以解决这个问题
//3、缺陷:还是基于回调的
//promise就是一个类
//1、promise有三个状态:成功态(resolve)、失败态(reject)、等待态(pending 不成功又不失败)
//2、用户自己决定失败的原因和成功的原因 成功和失败也是用户定义的
//3、promise默认执行器是立即执行
//4、promise的实例都拥有一个then方法,一个参数是成功的回调,另一个是失败的回调
//5、如果执行函数时发生了异常也会执行失败逻辑
//6、如果promise一但成功了就不能失败,反过来也是一样的(只有等待态的时候才能去更改状态)
let promise = new Promise((resolve,reject)=>{
reject('没发工资');
})
console.log(promise);
let promise = new Promise((resolve,reject)=>{
console.log(1);
});
console.log(2); // 1->2
//调用promise
let Promise = require('./promise');
let promise = new Promise((resolve,reject)=>{
console.log(1);
resolve('成功');
throw new Error('失败了'); //成功了就不会走失败,失败了就不会走成功
//resolve('成功');
});
promise.then((data)=>{
console.log('success',data);
},(err)=>{
console.log('fail',err);
});
//promise就是一个类
//1、promise有三个状态:成功态(resolve)、失败态(reject)、等待态(pending 不成功又不失败)
//2、用户自己决定失败的原因和成功的原因 成功和失败也是用户定义的
//3、promise默认执行器是立即执行
//4、promise的实例都拥有一个then方法,一个参数是成功的回调,另一个是失败的回调
//5、如果执行函数时发生了异常也会执行失败逻辑
//6、如果promise一但成功了就不能失败,反过来也是一样的(只有等待态的时候才能去更改状态)
const RESOLVED = 'RESOLVED';
const REJECTED = 'REJECTED';
const PENDING = 'PENDING';
class Promise{
constructor(executor){
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
let resolve = (value) =>{ //调用此方法就是成功
if(this.status === PENDING)
{
this.value = value;
this.status = RESOLVED;
}
}
let reject = (reason)=>{
if(this.status === PENDING)
{
this.reason = reason;
this.status = REJECTED;
}
}
try{
executor(resolve,reject); //立即执行
}catch(e){ //错误处理,需要直接走错误逻辑
console.log(e);
reject(e);
}
}
then(onFulfilled,onRejected){
if(this.status === RESOLVED)
{
onFulfilled(this.value);
}
if(this.status === REJECTED)
{
onRejected(this.reason);
}
if(this.status === PENDING)
{
console.log('等待');
}
}
}
module.exports = Promise;
//7、promise的then方法
let Promise = require('./promise');
let promise = new Promise((resolve,reject)=>{
setTimeout(()=>{
//resolve('成功');
reject('不成功');
},1000);
});
//1、promise调用then方法时可能当前的promise并没有成功, pending
promise.then((data)=>{
console.log('success',data);
},(err)=>{
console.log('failed',err);
});
//2、发布订阅模式,如果当前状态是pending时,我们需要将成功的回调和
//失败的回调存放起来,稍后调用resolve和reject的时候重新执行
promise.then((data)=>{
console.log('success1',data);
},(err)=>{
console.log('failed1',err);
});
//promise.js
const RESOLVED = 'RESOLVED';//成功
const REJECTED = 'REJECTED';//失败
const PENDING = 'PENDING';//等待态
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){
if(this.status === RESOLVED){
onFulfilled(this.value);
}
if(this.status === REJECTED){
onRejected(this.reason);
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{ //为什么要写成这样?
//todo...
onFulfilled(this.value);
});
this.onRejectedCallbacks.push(()=>{
//todo...
onRejected(this.reason);
});
}
}
}
module.exports = Promise;
//8、链式调用
name.txt
内容:age.txt
age.txt
内容:10
let fs = require('fs');
//error first 错误第一 异步方法无法通过try catch捕获异常
fs.readFile('./name.txt','utf8',(err,data)=>{
fs.readFile(data,'utf8',(err,data)=>{
console.log(data);
})
});
//变成promise
function read(filename){
return new Promise((resolve,reject)=>{
fs.readFile(filename,'utf8',(err,data)=>{
if(err)return reject(err);
resolve(data);
})
})
}
//1、promise成功和失败的回调的返回值,可以传递到外层的下一个then
//2、如果返回的是普通值的话(传递到下一次的成功中,不是错误不是promise就是普通值),可能还要promise的情况
//(会采用promise的状态,决定走下一次的成功还是失败)、出错的情况(一定会走到下一次的失败)
//3、错误处理 如果离自己最近的then没有错误处理(没有写错误函数)会向下找
//4、每次执行完promise.then方法后返回的都是一个“新的promise”(promise一旦成功或者失败就不能修改状态)
read('./name.txt').then((data)=>{
return 100;
},(err)=>{
return 200;
}).then((data)=>{
console.log('--------------',data);
},(err)=>{
console.log('---------------',err+'错误');
});
//D>node test.js
//--------------- 10
read('./name.txt').then((data)=>{
return read(data);
},(err)=>{
console.log("******",err);
}).then((data)=>{
console.log('---------------',data);
},(err)=>{
console.log('---------------',err+'错误');
});
//>node test.js
//--------------- 10
read('./name.txt').then((data)=>{
return data;
}).then((data)=>{
console.log('-------------',data);
},err=>{
console.log('-------------',err+'错误');
});
//>node test.js
//------------- age.txt
//>node test.js
//------------- Error: ENOENT: no such file or directory, open 'D:\important_file\笔记\name1.txt'错误
//9、普通值处理
let fs = require('fs');
let Promise = require('./promise');
function read(filename)
{
return new Promise((resolve,reject)=>{
fs.readFile(filename,'utf8',(err,data)=>{
if(err)reject(err);
resolve(data);
})
})
}
read('./name.txt').then((data)=>{
return 1;
}).then((data)=>{
});
//或者改写成:
let fs = require('fs');
let Promise = require('./promise');
let p1 = new Promise((resolve,reject)=>{ //调用p1.resolve(100)=>p1.then(data=) p2.resolve(1)=>p2.then(data)
resolve(100);
})
let promise2 = p1.then((data)=>{
return 1;
})
promise2.then((data)=>{
console.log(data);//1
})
//promise.js
const RESOLVED = 'RESOLVED';//成功
const REJECTED = 'REJECTED';//失败
const PENDING = 'PENDING';//等待态
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){
let x = onFulfilled(this.value);
resolve(x);
}
if(this.status === REJECTED){
onRejected(this.reason);
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
//todo...
onFulfilled(this.value);
});
this.onRejectedCallbacks.push(()=>{
//todo...
onRejected(this.reason);
});
}
});
return promise2;
}
}
module.exports = Promise;
//10、promise2状态的处理
let fs = require('fs');
let Promise = require('./promise');
//调用p1.resolve(100)=>p1.then(data)
//p2.resolve(1)=>p2.then(data)
let p1 = new Promise((resolve,reject)=>{
reject(100);
});
let p2 = p1.then((data)=>{
return 1;
},err=>{
return '失败';
});
p2.then((data)=>{
console.log(data,"******");
});
//promise.js
const RESOLVED = 'RESOLVED';//成功
const REJECTED = 'REJECTED';//失败
const PENDING = 'PENDING';//等待态
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){
let x = onFulfilled(this.value);
resolve(x);
}
if(this.status === REJECTED){
let x = onRejected(this.reason);
resolve(x);
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
//todo...
let x = onFulfilled(this.value);
resolve(x);
});
this.onRejectedCallbacks.push(()=>{
//todo...
let x = onRejected(this.reason);
resolve(x);
});
}
});
return promise2;
}
}
module.exports = Promise;
//如果返回的是一个promise呢?
let fs = require('fs');
let Promise = require('./promise');
let p1 = new Promise((resolve,reject)=>{
resolve(100);
});
let p2 = p1.then((data)=>{
return new Promise((resolve,reject)=>{//也有可能是throw new Error()
setTimeout(()=>{
resolve('OK');
},1000);
})
},err=>{
return '失败';
});
p2.then((data)=>{
console.log(data,"******");
},err=>{
});
//promise.js
const RESOLVED = 'RESOLVED';//成功
const REJECTED = 'REJECTED';//失败
const PENDING = 'PENDING';//等待态
const resolvePromise=(promise2,x,resolve,reject)=>{
};
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;