博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单实现 ES6 Promise
阅读量:7005 次
发布时间:2019-06-27

本文共 8087 字,大约阅读时间需要 26 分钟。

实现的一个简单的ES6 Promise(如果有错误的地方,希望大家能够不吝赐教)

仅实现Promise及.then方法
最下方有完整代码

开始

一个
promise对象接收的是一个
callback
这个
callback接收两个参数
(resolve,reject)
当我们在
callback内执行
resolve
reject的时候,就会调用
Promise内定义的
resolve
reject函数
然后,
resolve
reject函数会改变Promise的状态
所以它应该是像下面这样的
function MyPromise(callback) {  // 保存this值  var self = this  // 记录状态null为pending,true为resolved,false为reject  var state = null  // 记录resolve的参数  var param = null  // 执行传入的callback并改变promise对象状态  callback(resolve, reject)  // resolve方法  function resolve(data) {    // 改变状态    state = true    param = data  }  // reject方法  function reject(err) {    state = false    param = err  }}
但没有
then方法的
Promise对象是不完整的(完全没有用)
所以我们需要一个
then方法,要记住
then方法返回的也是一个
promise对象
then方法接收两个可选的参数
(onFulfilled, onRejected)(我们可以先忽略可选两个字)
then方法传进来的参数必须是函数,如果不是就要忽略(PromiseA+规范)(我们可以也先忽略这句话)
this.then = function (onFulfilled, onRejected) {    // 返回一个新的promise对象    return new self.constructor(function (resolve, reject) {      // then    })  }
接下来就是
then方法的具体实现了
then方法中
onFulfilled, onRejected的返回值会作为新promise的执行结果

onFulfilled, onRejected这两个函数要在promise的状态变为pending或resolved的时候才能分别执行

所以如果promise方法状态为resolvedrejected的话,我们就可以直接在then方法中执行resolve(onFulfilled(param))reject(onRejected(param))

this.then = function (onFulfilled, onRejected) {    // 返回一个新的promise对象    return new self.constructor(function (resolve, reject) {       if (state === true) {        // param是promise对象完成后的结果        resolve(onFulfilled(param))      } else if (state === false) {        reject(onRejected(param))      } else {        // 没有执行完毕,怎么办      }    })  }
但如果
promise的状态为
pending
由于原始
promise的状态我们是无法动态获取的,因此我们就需要在他执行状态改变的时候同时执行
onFulfilled
onRejected方法
我们可以把这个方法放在原始
promise对象的
resolve
reject方法中执行
因此我们要在
promise的对象定义中添加四个参数,分别记录
onFulfilled
onRejected,以及
then方法返回的新
promise对象的
resolve
reject
然后如果执行
then方法的时候
promise对象的状态为
pending的话,就将上述四个参数记录起来
// then方法返回的promise对象的resolve和rejectvar nextResolve = nullvar nextReject = null// 记录then方法的参数,onFulfilled和onRejectedvar asynconFulfilled = nullvar asynconRejected = null//then方法this.then = function (onFulfilled, onRejected) {    // 返回一个新的promise对象    return new self.constructor(function (resolve, reject) {      if (state === true) {        // param是promise对象完成后的结果        resolve(onFulfilled(param))      } else if (state === false) {        reject(onRejected(param))      } else {        nextResolve = resolve        nextReject = reject        asynconFulfilled = onFulfilled        asynconRejected = onRejected      }    })  }
接下来就是原始
promise中的
resolve
reject的重新实现
// resolve方法  function resolve(data) {    // 改变状态    state = true    param = data    nextResolve(asynconFulfilled(param))  }  // reject方法  function reject(err) {    state = false    param = err    nextReject(asynconRejected(param))  }
很简单不是吗
我们继续
上述实现我们一直没有考虑一个很重要的情况,如果
then方法返回的还是一个
promise对象,那么如果我们后边还有
then方法的话就要等待前一个
then方法中的
promise对象的状态从
pending变为完成
这要怎么做呢
什么时候可以认为then方法返回的
promise对象执行完毕了呢,这里我们就要用到
then方法(@_@,边写边用...),
resolve方法为例
var self = this// resolve方法function resolve(data) {  // 记录onFulfilled的执行结果  let parmise  // 改变状态  state = true  param = data  // 执行记录的onFulfilled  parmise = asynconFulfilled(param)  if(parmise === undefined){    // 如果parmise为undefined,就不能解析parmise.constructor  } else if (parmise.constructor === self.constructor) {    // 等待传递进来的promise对象执行完毕,然后根据传递进来的promise对象的状态执行resolve或reject    // 注意,这个param是形参,在then方法的promise中执行    promise.then(function (param) {      resolve(param)    }, function (param) {      reject(param)    })  } else {    // 这个是前边的then返回的不是promise对象的情况    resolve(promise)  }}
前面我们忽略了两点 (
then方法接收两个可选的参数(onFulfilled, onRejected)) 和 (
then方法传进来的参数必须是函数,如果不是就要忽略)
var self = this// resolve方法function resolve(data) {  // 记录onFulfilled的执行结果  var parmise  // 改变状态  state = true  param = data  // 执行记录的onFulfilled  // begin--------------  if (typeof onFulfilled === 'function') {    promise = onFulfilled(param)    if (promise === undefined) {      // 待补充    } else if (promise.constructor === self.constructor) {      // 注意,这个param是形参,在then方法的promise中执行      promise.then(function (param) {        resolve(param)      }, function (param) {        reject(param)      })    } else {      reject(promise)    }  } else {    // 如果onFulfilled不是function,忽略,直接resolve或reject    resolve(param)  }  // ---------------end}
上面begin到end之间的代码还要在
then方法调用,所以我们可以把这段代码抽象为一个函数
resolve
reject的原理相同,只要注意
如果不是function 的话需要执行reject

onFulfilled和 
onRejected只有在[执行环境]堆栈仅包含
平台代码时才可被调用
所以将上述
begin-end之间的代码放到
seTimeout中执行(浏览器环境)
function resolve(data) {  // 记录onFulfilled的执行结果  var parmise  // 改变状态  state = true  param = data  // 执行记录的onFulfilled  window.setTimeout(function () {    // begin--------------    // 上述代码    // ---------------end  }, 0)}
下面是完整代码
注:没有实现正确的事件循环
// 简单实现ES6 Promisefunction MyPromise(callback) {  // 保存this值  var self = this  // 记录状态null为pending,true为resolved,false为reject  var state = null  // 记录resolve的参数  var param = null  // then方法返回的promise对象的resolve和reject  var nextResolve = null  var nextReject = null  // 记录then方法的参数,onFulfilled和onRejected  var asynconFulfilled = null  var asynconRejected = null  // 执行并改变promise对象状态  callback(resolve, reject)  // then方法  this.then = function (onFulfilled, onRejected) {    // 返回一个新的promise对象    return new self.constructor(function (resolve, reject) {      // 判断异步代码是否执行完毕(是否resolve或reject)      // 若执行完毕就在then方法中立即执行,否则将四个参数记录下来,等待state就绪后再执行doAsyn*函数      if (state === true) {        doAsynconFulfilled(onFulfilled, resolve, reject)      } else if (state === false) {        doAsynconRejected(onRejected, resolve, reject)      } else {        nextResolve = resolve        nextReject = reject        asynconFulfilled = onFulfilled        asynconRejected = onRejected      }    })  }  // resolve方法  function resolve(data) {    // 改变状态    state = true    param = data    if(nextResolve){        doAsynconFulfilled(asynconFulfilled, nextResolve, nextReject)    }  }  // reject方法  function reject(err) {    state = false    param = err    if(nextReject){        doAsynconRejected(asynconRejected, nextResolve, nextReject)    }  }  // 核心方法(我觉得是)  function doAsynconFulfilled(onFulfilled, resolve, reject) {      window.setTimeout(function () {        // 判断onFulfilled是否为function,不是则忽略        if (typeof onFulfilled === 'function') {          // 执行onFulfilled方法获取返回值promise()          let promise = onFulfilled(param)          // 如果promise为undefined 执行 if          // 如果promise为MyPromise对象 执行 else if          // 如果promise为非MyPromise对象 执行 else          if (promise === undefined) {            resolve(param)            // 待补充          } else if (promise.constructor === self.constructor) {            // 等待传递进来的promise对象执行完毕,然后根据传递进来的promise对象的状态执行resolve或reject            promise.then(function (param) {              resolve(param)            }, function (param) {              reject(param)            })          } else {            // 执行then方法返回的对象的resolve            resolve(promise)          }        } else {          // 传递参数          resolve(param)        }      }, 0)      }  function doAsynconRejected(onRejected, resolve, reject) {    window.setTimeout(function () {        if (typeof onRejected === 'function') {          let promise = onRejected(param)          if (promise === undefined) {            reject(param)            // 待补充          } else if (promise.constructor === self.constructor) {            promise.then(function (param) {              resolve(param)            }, function (param) {              reject(param)            })          } else {            reject(promise)          }        } else {          // 传递错误信息          reject(param)        }    }, 0)  }}// 测试使用var b = function (message) {    return new MyPromise(function (resolve, reject) {        document.body.onclick = function () {            resolve('click:' + message)        }    })}var a = new MyPromise(function (resolve, reject) {  resolve(123)}).then(function (message) {    return b(message)}).then().then(function (message) {    console.log('final:' + message)},function (err) {    console.log('final:' + err)})console.log('window')
当然还有Promise.all等方法。
完毕!

转载地址:http://kpytl.baihongyu.com/

你可能感兴趣的文章
Spring IOC 容器源码分析 - 创建单例 bean 的过程
查看>>
MySQL数据库1
查看>>
Android入门篇(五)Activity跳转
查看>>
每天一个lodash方法-differenceBy
查看>>
linux命令之htpasswd
查看>>
Nginx负载均衡配置
查看>>
flow的采集与分析---clickhouse的简介和安装
查看>>
cgo的指针传递
查看>>
JS 实现抛物线动画
查看>>
前端是不是大于后端?
查看>>
小程序onLaunch,onLoad 执行生命周期
查看>>
Electron学习-安装
查看>>
python学习笔记02-数据类型
查看>>
关于Java中异常的总结
查看>>
算法练习
查看>>
容器化应用: Minishift 搭建镜像仓库的可视化管理控制台
查看>>
Canvas 涂鸦
查看>>
webpack模块化原理-Code Splitting
查看>>
如何从两个List中筛选出相同的值
查看>>
.NET Core 2将Visual Basic带到了Linux和macOS平台
查看>>