Coder Social home page Coder Social logo

promise about blog HOT 1 OPEN

cisen avatar cisen commented on August 16, 2024
promise

from blog.

Comments (1)

cisen avatar cisen commented on August 16, 2024

最简单实现

  // 如果有obj有then属性函数,则返回一个then函数,this绑定到obj,接受使用then时的参数
  function getThen(obj) {
      var then = obj && obj.then;
      if (obj && typeof obj === 'object' && typeof then === 'function') {
          return function appyThen() {
              // this绑定到boj并执行then方法
              then.apply(obj, arguments);
          };
      }
  }
// 如果resolve(res)的res还是一个promise,则先执行完自己的resolve,再继续执行res的then方法,this绑定到res
  // 这里可以将res的所有then方法递归完
  function executeCallback(type, x) {
      var isResolve = type === 'resolve',
          thenable;
      // 如果客户使用resolve(res)时,res是一个函数或者对象,x就是res,则去判断
      // res是否有then属性函数,有则返回一个绑定res作为this的函数
      if (isResolve && (typeof x === 'object' || typeof x === 'function')) {
          try {
              // 如果x有then方法,则返回一个then函数,this绑定到x,参数是使用thenable函数时thenable函数的参数
              // thenable是一个函数
              thenable = getThen(x);
          } catch (e) {
              return executeCallback.bind(this)('reject', e);
          }
      }
      if (isResolve && thenable) {
          // 递归执行resolve(res)的res.then方法,并绑定this到第一个res上
          // 一开始this指向最外层的promise,所以执行完resolve后就能执行then了
          // 这里执行this所在的then
          executeResolver.bind(this)(thenable);
      } else {
          this.state = isResolve ? RESOLVED : REJECTED;
          this.data = x;
          this.callbackQueue.forEach(v => v[type](x));
      }
      return this;
  }
// 用于执行 new Promise(function(resolve, reject){}) 中的resove或reject方法
  function executeResolver(resolver) {
      //[标准 2.3.3.3.3] 如果resove()方法多次调用,只响应第一次,后面的忽略
      var called = false,
      // 把this存起来,让执行onSuccess还能访问到这个promise对象的属性
          _this = this;
      // 执行reject,没有返回
      function onError(y) {
          if (called) {
              return; }
          called = true;
          //[标准 2.3.3.3.2] 如果是错误 使用reject方法
          executeCallback.bind(_this)('reject', y);
      }
      // 执行resolve函数, 这里的执行不知道是什么时候的执行,因为是异步的
      // 这个函数是由用户去触发执行的,就是那个resolve(res);
      function onSuccess(r) {
          if (called) {
              return; }
          called = true;
          // 一开始this指向最外层的promise,所以执行完resolve后就能执行then了
          executeCallback.bind(_this)('resolve', r);
      }
      try {
          // 执行成功的函数是由封装的函数作为一个参数提供给用户使用的
          //[标准 2.3.3.3.4] 如果调用resolve()或reject()时发生错误,则将状态改成rejected,并将错误reject出去
          resolver(onSuccess, onError);
      } catch (e) {
          onError(e);
      }
  }

function Promise(resolver) {
      if (resolver && typeof resolver !== 'function') {
          throw new Error('Promise resolver is not a function') }
      // PENDING Fulfilled  Rejected
      this.state = PENDING;
      //当前promise对象的数据(成功或失败)
      this.data = UNDEFINED;
      //当前promise对象注册的回调队列
      this.callbackQueue = [];

      if (resolver) executeResolver.call(this, resolver);
  }
  Promise.prototype.then = function(onResolved, onRejected) {
      if (typeof onResolved !== 'function' && this.state === RESOLVED ||
          typeof onRejected !== 'function' && this.state === REJECTED) {
          return this;
      }

      var promise = new this.constructor();

      if (this.state !== PENDING) {
          var callback = this.state === RESOLVED ? onResolved : onRejected;
          executeCallbackAsync.bind(promise)(callback, this.data);
      } else {
          this.callbackQueue.push(new CallbackItem(promise, onResolved, onRejected))
      }
      // 链式调用
      return promise;
  }
  Promise.prototype['catch'] = function(onRejected) {
      return this.then(null, onRejected);
  }
# 总结
1. resolve函数执行的时候通过`var promise = new this.constructor();`生成一个promise返回
2. resolve之后是如何切换到then的,这是一个问题

from blog.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.