Promise的使用及简单实现

一. promise是什么

简单来说是一种异步流程的控制手段

  • 所谓Promise ,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise 对象的状态不受外界影响

  • 在JavaScript的世界中,所有代码都是单线程执行的。 由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。

    异步执行容易造成回调地狱

    例如:

    $.ajax(
        success(){
            $.ajax(
                success(){
                    
                }
            )
        }
    )
    复制代码

    使用promise的链式调用就可以很好的解决这个问题

    例如:vue-resource

    this.$http.post(url,parms).then(res => {
        console.log(res)
    },err => {
        
    }).then(res=>{
        
    },err=>{
        
    })
    复制代码

二.promise的使用及方法

ES6规定,Promise对象是一个构造函数,用来生成Promise实例。Promise本身有all、race、reject、resolve这几个方法

  • Promise只有一个参数 叫excutor执行器,默认new时就会调用
    let p = new Promise((resolve,reject)=>{ 
      // 默认promise中的executor是同步执行的
       resolve('买');
    });
    // then方法是异步调用的,事件环
    p.then((value)=>{ // value成功的原因
      console.log(value);//买
    },(err)=>{ // err失败的原因
    });
    复制代码

注意:then方法是Promise实例上的方法

  • Promise的reject、resolve方法

    promise有三种状态:resolve 成功 reject 失败 pending 等待态。 如果一旦promise成功了就不能失败,相反也是一样的,只有状态是等待的状态时才可以转化状态。pending->reject(resolve)

    1.Promise.resolve() 返回一个成功的promise

    2.Promise.reject() 返回一个失败的promise

    例:

    
    let fs = require('fs'); // fileSystem
    function read(url) {
      return new Promise((resolve, reject) => {
        fs.readFile(url, 'utf8', function (err, data) {
          if (err) reject(err);//成功返回
          resolve(data);//失败返回
        })
      })
    }
    
    复制代码
  • Promise的all、race方法

    promise可以支持多个并发的请求,获取并发请求中的数据

    1.Promise.all

    这可能是个很有用的方法,它可以统一处理多个Promise。Promise.all能将多个Promise实例包装成一个Promse实例

        let Promise1 = new Promise(function(resolve, reject){})
        let Promise2 = new Promise(function(resolve, reject){})
        let Promise3 = new Promise(function(resolve, reject){})
        
        let p = Promise.all([Promise1, Promise2, Promise3])
        
        p.then(funciton(){
          // 三个都成功则成功  
        }, function(){
          // 只要有失败,则失败 
        })
    
    复制代码

    2.Promise.race()

    与all方法类似,也可以将多个Promise实例包装成一个新的Promise实例 不同的是,all时大Promise的状态由多个小Promise共同决定,而race时由第一个转变状态的小Promise的状态决定,第一个是成功态,则转成功态,第一个失败态,则转失败态。

    ** 简单来说就是赛跑,处理多请求只取最快的 **

    let fs = require('fs'); // fileSystem
    function read(url) {
      return new Promise((resolve, reject) => {
        fs.readFile(url, 'utf8', function (err, data) {
          if (err) reject(err);//成功返回
          resolve(data);//失败返回
        })
      })
    }
    Promise.race([read('1.txt'),read('2.txt')]).then((data)=>{
      console.log(data);//最快读取完成功则成功
    },err=>{
      console.log(err);//最快读取完失败则失败
    });
    
    复制代码

三. promise的简单实现

通过上文我们已经知道Promise是一个构造函数,我们可以使用ES6的class类来创建一个Promise

下面我们创建一个class类来完成promise的then、reject、resolve方法

class Promise {
   constructor(executor) {
     // 默认状态是等待态
     this.status = 'pending';
     this.value = undefined;
     this.reason = undefined;
     // 存放成功的回调
     this.onResolvedCallbacks = [];
     // 存放失败的回调
     this.onRejectedCallbacks = [];
     let resolve = (data) => {
       if (this.status === 'pending') {
         this.value = data;
         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); // promise失败了
     }
   }
   then(onFulFilled, onRejected) {
     if (this.status === 'resolved') {
       onFulFilled(this.value);
     }
     if (this.status === 'rejected') {
       onRejected(this.reason);
     }
     // 当前既没有完成 也没有失败
     if (this.status === 'pending') {
       // 存放成功的回调
       this.onResolvedCallbacks.push(() => {
         onFulFilled(this.value);
       });
       // 存放失败的回调
       this.onRejectedCallbacks.push(() => {
         onRejected(this.reason);
       });
     }
   }
 }
 module.exports = Promise;
 
复制代码

完成了基本的功能,我们可以使用自己写的promise来测试一下


 let Promise = require('./promise');//引入
 let p = new Promise((resolve,reject)=>{
   resolve(123);
   reject(123);
 });
 p.then((data)=>{
   console.log('s',data);//s,123
 },(err)=>{
   console.log('e',err);//e,123
 });
 
复制代码

总结:

  • Promise是一种异步流程的控制手段

  • 每一个promise的实例上都有一个then方法,then方法中有两个参数,一个参数叫成功的函数 ,一个是失败的函数

  • Promise可以链式调用,并且可以支持多个并发的请求,获取并发请求中的数据

  • 如果一旦promise成功了就不能失败,相反也是一样的。只有状态是等待的状态时 才可以转化状态

  • Promise可以解决异步的问题,但不能说promise本身是异步的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值