zoukankan      html  css  js  c++  java
  • 简单模拟 Promise

    class promise {
      constructor(fn) {
        this.data = null;
        this.err = null;
    
        this.isPromise = false;
    
        this.errFn = null;
        this.queue = [];
    
        this.run = this.run.bind(this);
        this.error = this.error.bind(this);
        this.then = this.then.bind(this);
        this.catch = this.catch.bind(this);
        this.reslove = this.reslove.bind(this);
        this.reject = this.reject.bind(this);
        this.setData = this.setData.bind(this);
        this.getData = this.getData.bind(this);
        this.setQueue = this.setQueue.bind(this);
        this.setErrFn = this.setErrFn.bind(this);
        this.getErrFn = this.getErrFn.bind(this);
        this.setPromise = this.setPromise.bind(this);
        this.getPromise = this.getPromise.bind(this);
    
        fn(this.reslove, this.reject);
    
        return this;
      }
    
      setPromise() {
        this.isPromise = !this.isPromise;
      }
    
      getPromise() {
        return this.isPromise;
      }
    
      setErrFn(fn) {
        this.errFn = fn;
      }
    
      getErrFn() {
        return this.errFn;
      }
    
      setQueue(fn) {
        this.queue.push(fn);
      }
    
      getQueue() {
        return this.queue;
      }
    
      setData(data) {
        this.data = data;
      }
    
      getData() {
        return this.data;
      }
    
      setErr(err) {
        this.err = err;
      }
    
      getErr() {
        return this.err;
      }
    
      reslove(data) {
        if (this.getPromise()) return;
        this.setPromise();
        this.setData(data);
        this.run();
      }
    
      reject(err) {
        if (this.getPromise()) return;
        this.setPromise();
        this.setErr(err);
        this.error();
      }
    
      then(fn) {
        this.setQueue(fn);
        return this;
      }
    
      catch(fn) {
        this.setErrFn(fn);
      }
    
      run() {
        const queue = this.getQueue();
        let ret = this.getData();
        for(let i = 0; i < queue.length; i++) {
          // 下面三种方式都可以实现想要的效果
          process.nextTick(() => {
            ret = queue[i](ret);
          });
          // setImmediate(() => {
          //   ret = queue[i](ret);
          // });
          // setTimeout(() => {
          //   ret = queue[i](ret);
          // }, 0);
        }
      }
    
      error() {
        // 下面三种方式都可以实现想要的效果
        process.nextTick(() => {
          this.setErrFn(fn)
        });
        // setImmediate(() => {
        //   this.setErrFn(fn)
        // });
        // setTimeout(() => {
        //   this.getErrFn()(this.getErr());
        // }, 0);
      }
    
    }
    
    const p = new promise((res, rej) => {
      setTimeout(() => {
        console.log('s1');
        setTimeout(() => {
          console.log('s2');
          setTimeout(() => {
            console.log('s3');
            res('res');
            rej('rej');
            console.log('s4');
          }, 1000);
        }, 1000);
      }, 1000);
    });
    
    let pp = p
    .then((data) => {
      console.log(data);
      return 't2';
    })
    .then((data) => {
      console.log(data);
      return 't3';
    });
    
    pp.then((data) => {
      console.log(data);
    }).catch((err) => {
      console.log(err);
    });

    // 输出
    // s1
    // s2
    // s3
    // s4
    // res
    // t2
    // t3

    上面代码只是简单的进行基础模拟,让回调可以串行化,没有做错误处理、 API 扩展、参数格式化等操作。

     Promise 通过高层次的回调抽离,将代码编写方式从回调改写成了串行,需要在熟练使用的基础上对其内核进行深入的理解才能更加灵活地运用。

  • 相关阅读:
    timer.Interval用法简介
    .net 未被引用的错误
    将Sql查询语句获取的数据插入到List列表里面
    .net 里面打不出来ConfigurationManager
    .net MVC框架里怎么写控件
    数据库里面几个字符类型的区别
    怎么在.net里面解析JSON文件?
    SqlCommand.ExecuteScalar()方法
    git学习笔记
    可变参数的lambda表达式
  • 原文地址:https://www.cnblogs.com/jyuf/p/8566773.html
Copyright © 2011-2022 走看看