promise 是什么
Promise 是为了解决异步回调问题,处理异步回调使得代码层次更加清晰,便于理解,更加容易维护
复制代码
首先我们简单实用一个一下es6的promise 然后去简单实现一下,用setTimeout 简单的模拟异步
function fn1(resolve,reject){
setTimeout(()=>{
console.log(1)
resolve(1);
})
}
new Promise(fn1).then((data)=>{
console.log('data:'+data); // data : 1
})
// 结果是先打出一个1 然后在打出 data: 1
复制代码
简单的实现上边代码的promise
- 首先Promise 是一个函数 有两个参数 resolve 和 reject 一个成功的参数一个失败的参数
- promise 有三个状态 pending 等待态 fulfilled 成功态 rejected 失败态
- 如果 函数没有返回成功或者失败 那么 他一直就是等待态, 需要两个数组把函数存起来,等待他的状态变化 再去执行相对的函数 设置两个数组 一个为 成功的数组 onResolvedCallbacks 一个为失败的数组 onRejectedCallbacks
- promise 一旦成功 就不能 失败 一旦失败就不能成功 不能进行转换 所以执行成功或者失败的函数时 要判断是不是 等待态 如果是等待态 在去执行 成功或失败的函数 并且把其变成响应的状态,把其值 改变,并且执行回调函数
复制代码
class Promise{
constructor(exectour){
this.status="pending" //定义状态
this.onResolvedCallbacks=[]; // 成功函数的数组
this.onRejectedCallbacks=[]; // 失败函数的数组
this.value=undefined; //成功的返回值
this.season=undefined; //失败的返回值
let resolve=(value)=>{ // 成功的回调函数
if(this.status==='pending'){
this.status='fulfilled';
this.value=value;
this.onResolvedCallbacks.forEach(fn=>fn(this.value))
}
}
let reject=(reason)=>{ 失败的回调函数
if(this.status==='pending'){
this.status='rejected';
this.reason=reason;
this.onRejectedCallbacks.forEach(fn=>fn(this.reason))
}
}
exectour(resolve,reject);
}
}
module.exports=Promise;
复制代码
上边代码的then 方法
- then 的参数有两个,第一个参数是成功的参数 onFulfilled,第二个参数是失败的参数 onRejected
- 执行到then 的时候 有三个状态 成功 失败 和等待 成功的时候执行成功的函数 失败的时候执行失败的函数,等待的时候就存到他们各自函数的数组里边
复制代码
class Promise{
constructor(exectour){
//code
}
then(onFulfilled,onRejected){
if(this.status==='fulfilled'){//成功态
onFulfilled(this.value)
}
if(this.status==='rejected'){//失败态
this.onRejected(this.reason)
}
if(this.status==='pending'){//等待态
this.onResolvedCallbacks.push(onFulfilled);
this.onRejectedCallbacks.push(onRejected);
}
}
}
module.exports=Promise;
复制代码
完整代码
class Promise{
constructor(exectour){
this.status="pending" //定义状态
this.onResolvedCallbacks=[]; // 成功函数的数组
this.onRejectedCallbacks=[]; // 失败函数的数组
this.value=undefined; //成功的返回值
this.season=undefined; //失败的返回值
let resolve=(value)=>{ // 成功的回调函数
if(this.status==='pending'){
this.status='fulfilled';
this.value=value;
this.onResolvedCallbacks.forEach(fn=>fn(this.value))
}
}
let reject=(reason)=>{ 失败的回调函数
if(this.status==='pending'){
this.status='rejected';
this.reason=reason;
this.onRejectedCallbacks.forEach(fn=>fn(this.reason))
}
}
exectour(resolve,reject);
}
then (onFulfilled,onRejected){
if(this.status==='fulfilled'){//成功态
onFulfilled(this.value)
}
if(this.status==='fulfilled'){//失败态
this.onRejected(this.reason)
}
if(this.status==='pending'){//等待态
this.onResolvedCallbacks.push(onFulfilled);
this.onRejectedCallbacks.push(onRejected);
}
}
}
module.exports=Promise;
复制代码
使用 自己写的promise
const Promise= require('./Promise');
function fn1(resolve,reject){
setTimeout(()=>{
console.log(1)
resolve(1);
})
}
new Promise(fn1).then((data)=>{
console.log('data:'+data); // data : 1
},reason=>{
console.log('raeson'+reson)
})
复制代码
总结 这就简单实现了一个漏洞百出的promise ,后边将继续完善我们promise ,上边的promise如果回调的时候 抛出一个异常那么我们现在实现的promise 是不会做出反应的所以要考虑一下这种情况
class Promise{
constructor(exectour){
//code
try{
exectour(resolve,reject);
}catch(e){
reject(e);
}
}
}
复制代码
我们目前完成的promise 是不能链式的 所以下一步就是实现链式,要想实现链式 那么 回调函数返回的就是一个promise 才会现实链式
根据 promise a+的规范 返回一个名字叫 promise2 的一个promise
x 是回调函数的返回值,要看看 是不是promise 如果是 取他的结果,作为promise2 成功的结果
如果返回的是一个普通值, 作为promise2 成功的结果
然后我们用 resilvePromise 解析 x 和promise2 之间的关系
复制代码
class Promise{
constructor(exectour){
//code
}
then(onFulfilled,onRejected){
let promise2
if(this.status==='fulfilled'){//成功态
promise2=new Promise((resolve,reject)=>{
let x= onFulfilled(this.value);
resolvePromise(promise2,x,resolve,reject)
})
}
if(this.status==='fulfilled'){//失败态
promise2=new Promise((resolve,reject)=>{
let x= this.onRejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
})
}
if(this.status==='pending'){//等待态
promise2=new Promise((resolve,reject)=>{
this.onResolvedCallbacks.push(()=>{
let x=onFulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
});
this.onRejectedCallbacks.push(()=>{
let x= this.onRejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
});
})
}
return promise2 // 调用then后返回一个新的promise
}
}
复制代码
那么我们接下来实现 resolvePromise解析 x 和promise2 之间的关系
function resolvePromise(promise2,x,resolve,reject){
// 首先判断promise2 和x 是不是同一个promise 如果是报错
if(promise2===x){
reject(new TypeError('循环引用'))
}
//如果x不是null 并且 是对象或者函数 我们进进一步去做处理 否则我们 认为他是一个值 直接传成功就可以了
if(x!==null && (typeof x === 'object' || typeof x ==='function')){
//
let called //防止成功或失败再去调用
try{ //防止取的then 出现异常
let then=x.then
if(typeof then=='function'){//如果then 是一个函数我们就认为他是一个promise
then.call(x,y=>{ // call 第一个参数是this ,后面的是成功的回调和失败的回调
//y 是promise就继续递归解析
if(called) return false;
called= true;
resolvePromise(promise2,y,resolve,reject);
},r=>{
if(called) return false;
called= true;
reject(r)
})
}else{
resolve(x) //then shi 一个普通对象 就直接成功
}
}catch(e){
if (called) return;
called = true;
reject(e);
}
}else{
resolve(x);
}
}
复制代码
那么 我们基本上就完成了一个promise 不过promise 的几个方法还没有实现 那么我们继续完成promise上的另几个方法
class Promise {
//code
catch(onRejected) {
// catch就是then的没有成功的简写
return this.then(null, onRejected);
}
}
Promise.resolve = function (val) {
return new Promise((resolve, reject) => resolve(val))
}
Promise.reject = function (val) {
return new Promise((resolve, reject) => reject(val));
}
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject);
}
});
}
Promise.all = function (promises) {
return new Promise((resolve,reject)=>{
let arr = [];
let i = 0; // i的目的是为了保证获取全部成功,来设置的索引
function processData(index,data) {
arr[index] = data;
i++;
if (i === promises.length){
resolve(arr);
}
}
for(let i = 0;i<promises.length;i++){
promises[i].then(data=>{
processData(i,data);
}, reject);
}
})
}
Promise.deferred = Promise.defer = function () {
let dfd = {};
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
})
return dfd;
}
复制代码
这就基本完成了一个promise 代码和语言的归纳还比较稚嫩,希望大家多多指点。