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

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

Promise本意是承诺.主要目的是为了解决在需要多个异步操作的时候.产生的回调嵌套.在es6没出来前.用bluebird来实现.与javas中的Q模块类似.

Promise对象实例创建的过程中有三种状态, Pending、Fulfilled、Rejected. Fulfilled与Rejected间不能相互转换

promise

promise的使用与原理实现

then

promise.then用于链式调用,每次执行时都会返回一个新的promise对象

all

接收一个promise数组,如果状态都为resolve则返回Promise的resolve状态,如果某个promise状态为reject则返回Promise的reject状态

race

接收一个promise数组, 比谁跑的快.返回第一完成的Promise状态

promise功能的简单实现

const PENDING = 'pending'const FULFILLED = 'fulfilled'const REJECTED = 'rejected'function Promise(executor) {  let self = this  // 初始化  self.status = PENDING  // 定义回调  self.onResolvedCallbacks = []  self.onRejectedCallbacks = []  function resolve(value) {    if (value != null && value.then && typeof value.then === 'function') {      return value.then(resolve, reject)    }    // 如果是初始状态.则改变成成功状态    setTimeout(() => {      if (self.status === PENDING) {        self.status = FULFILLED        self.value = value        // 调用所有的成功        self.onResolvedCallbacks.forEach(cb => cb(self.value))      }    })  }  function reject(reason) {    setTimeout(() => {      if (self.status === PENDING) {        self.status = REJECTED        self.value = reason        self.onRejectedCallbacks.forEach(cb => cb(self.value))      }    })  }  try {    // 捕获函数执行时出现的异常    executor(resolve, reject)  } catch(e) {    reject(e)  }}function resolvePromise(promise2, x, resolve, reject) {  if (promise2 === x) {    return reject(new TypeError('循环引用'))  }  let called = false  if (x instanceof Promise) {    if (x.status === PENDING) {      x.then(function(y){        resolvePromise(promise2, y, resolve, reject)      }, reject)    } else {      x.then(resolve, reject)    }  } else if(x != null && ((typeof x === 'object') || (typeof x.then === 'function'))) {    // 兼容性处理    consoole.log('兼容性处理')    try {      let then = x.then      if (typeof then === 'function') {        then.call(x, (y) => {          if (called) return          called = true          resolvePromise(promise2, y, resolve, reject)        }, (err) => {          if (called) return          called = true          reject(err)        })      } else {        resolve(x)      }    } catch(e) {      if (called) return      called = true      reject(e)    }  } else {    // x是一个普通的值    resolve(x)  }}Promise.prototype.then = function(onFulfilled, onRejected) {  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(value) {return value}  onRejected = typeof onRejected === 'function' ? onRejected : function(reason) {throw reason}  let self = this  let promise2  if (self.status == FULFILLED) {    return  promise2 = new Promise((resolve, reject) => {      setTimeout(() => {        try {          let x = onFulfilled(self.value);          //如果获取到了返回值x,会走解析Promise的过程          resolvePromise(promise2, x, resolve, reject);        } catch(e) {          //如果执行成功的回调过程中出错了,用错误原因把Promise2 reject          reject(e);        }      })    })  }  if (self.status == REJECTED) {    return  promise2 = new Promise((resolve, reject) => {      setTimeout(() => {        try {          let x = onRejected(self.value);          resolvePromise(promise2, x, resolve, reject);        } catch(e) {          reject(e);        }      })    })  }  if(self.status == PENDING){    return promise2 = new Promise(function(resolve,reject){      self.onResolvedCallbacks.push(function(){          try{            let x =onFulfilled(self.value);            //如果获取到了返回值x,会走解析promise的过程            resolvePromise(promise2,x,resolve,reject);          }catch(e){            reject(e);          }       });      self.onRejectedCallbacks.push(function(){          try{            let x =onRejected(self.value);            resolvePromise(promise2,x,resolve,reject);          }catch(e){            reject(e);          }      });    });   }}Promise.prototype.catch = function(onRejected) {  this.then(null, onRejected)}Promise.race = function(promises) {  return new Promise((resolve, reject) => {    for (let i = 0; i < promises.length; i++) {      promises[i].then(resolve, reject)    }  })}Promise.deferred = Promise.defer = function(){  let defer = {};  defer.promise = new Promise((resolve,reject) => {    defer.resolve = resolve;    defer.reject = reject;  });  return defer;}Promise.resolve = function (value) {  return new Promise((resolve, reject) => resolve(value))}Promise.reject = function (reason) {  return new Promise((resolve, reject) => reject(reason))}Promise.all = function (promises) {  return new Promise((resolve, reject) => {    let done = gen(promises.length, resolve)    for (let i = 0; i < promises.length; i++) {      promises[i].then(val => {        done(i, val)      }, reject)    }  })}function gen(i, val) {  let count = 0, result = []  return function (i, val) {    result[i] = val    if (++count === i) {      resolve(result)    }  }}module.exports = Promise

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

你可能感兴趣的文章
六、nginx搭建织梦DedeCms网站
查看>>
Tair学习小记
查看>>
网卡绑定(服务器&&交换机),缓存服务器Squid架构配置
查看>>
web网站加速之CDN(Content Delivery Network)技术原理
查看>>
打算写一款框架来提高自己 写个结构吧
查看>>
vue学习:10、第一个项目,实践中遇到的问题
查看>>
sed的基本用法
查看>>
一个不错的shell 脚本入门教程
查看>>
JVM、GC相关资料
查看>>
dell r620装cenots7遇到的问题
查看>>
Ansible之playbook的使用
查看>>
ansible模块批量管理
查看>>
redis命令 - GET
查看>>
[Maven问题总结]Jetty9的Maven配置——嵌入式服务器
查看>>
httpd.conf的基本设置
查看>>
RHEL/Centos7新功能
查看>>
第一部分 思科九年 一(1)
查看>>
DBA日常工作职责
查看>>
Redis的持久化
查看>>
linux安装NFS服务器学习
查看>>