Focus onThe front small OuRead more original technical articles

Review: Progressive interpretation of Promise source code

Complete code + notes, can be read

Promise. Resolve – the source code

/** The Promise constructor's resolve property points to the function argument value: resolve value */
Promise.resolve = function (value) {
  /* If the constructor property of the resolution value points to the Promise constructor (i.e., the resolution value is a Promise instance) */
  if (value && typeof value === 'object' && value.constructor === Promise) {
    return value // Return this Promise instance
  }

  /* The resolution value is not a Promise instance, returns the new Promise instance and calls its success callback, with the argument as the resolution value */
  return new Promise(function (resolve) {
    resolve(value)
  })
}
Copy the code
  • callPromise.resolve(), which is equivalent tonew Promise(resolve=>{resolve()}), parameter as the solution value
  • If the parameter isPromiseObject, the object is returned

Promise. Reject – the source code

/** The reject property of the Promise constructor, which points to the function argument value: reject reason */
Promise.reject = function (value) {
  /* Returns the new Promise instance and invokes its failure callback, with arguments as the rejection reason */
  return new Promise(function (resolve, reject) {
    reject(value)
  })
}
Copy the code
  • callPromise.reject, which is equivalent tonew Promise(resolve=>{reject()}), parameter as the reason for rejection
  • withPromise.resolve()The difference is, even if the parameter isPromiseObject, also as a wholenew PromiseThe reason for rejecting a failed callback

Promise. Resolve & Promise. Reject – Phase testing

  • Promise.resolveandPromise.rejectIn fact, isnew PromiseThe encapsulation, pay attention to observeParameters forPromiseExample is the difference between the two results
Promise.resolve(3) // 'resolve:3', the resolve value is a basic type
/* self is the Promise {_state: 1, _handled: false, _value: 3, _deferreds: []} */
Promise.resolve({ val: 3 }) // 'resolve:[object object]', resolve value is common object
/* self is the Promise {_state: 1, _handled: false, _value: {val: 3}, _deferreds: []} */
Promise.resolve(Promise.resolve(3)) // 'resolve:3', resolve the value of about an instance
/* self is the Promise {_state: 1, _handled: false, _value: 3, _deferreds: []} */
Promise.resolve({
  // The solution value is thenable object
  value: 3.then: function () {
    console.log(this) // {value: 3, then: [Function: then]}, this refers to the solution value itself
    console.log(this.value) / / 3}})Promise.reject(3) // 'reject:3', reject is a basic type
/* self is the Promise {_state: 2, _handled: false, _value: 3, _deferreds: []} */
Promise.reject(Promise.resolve(3)) // 'reject:[object object]', reject ()
/* self as Promise {_state: 2, _handled: false, _value: 1, _handled: false, _value: 3, _deferreds: [] }, _deferreds: [] } */
Copy the code

Promise. _immediateFn – the source code

/** The _immediateFn property of the Promise constructor points to the function * parameter fn: the method to be executed (** note: an asynchronous call **) */
var setTimeoutFunc = setTimeout
var setImmediateFunc = typeofsetImmediate ! = ='undefined' ? setImmediate : null // Determine whether the browser has the setImmediate method

Promise._immediateFn =
  typeof setImmediateFunc === 'function' // setImmediateFunc is a function object
    ? function (fn) {
        setImmediateFunc(fn) // Call the fn method asynchronously (immediately)
      }
    : function (fn) {
        setTimeoutFunc(fn, 0) // Call the fn method asynchronously (0 ms later)
      }
Copy the code
  • Depending on whether the browser has itsetImmediateMethod, pointing to different
  • But they all end up executing the incoming methods asynchronously

Promise. _unhandledRejectionFn – the source code

/** The _unhandledRejectionFn property of the Promise constructor points to the function * argument err: rejection reason */
Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
  if (typeof console! = ='undefined' && console) {
    console.warn('Possible Unhandled Promise Rejection:', err) // The browser gives a warning}}Copy the code
  • Encapsulation: failed callback is warned in the browser

Finale () – Test code

  • Update handwriting testsfinale()Method, add browser warning, make it more close to the source code, easy to do stage testing
/** Test the call () method * argument self: the call instance */
function finale(self) {
  // console.log(self)
  // if (self._state === 1) {
  // console.log('resolve:' + self._value)
  // } else if (self._state === 2) {
  // console.log('reject:' + self._value)
  // } else if (self._state === 3) {
  // console.log('resolve value is Promise')
  // }

  /* If the _state value is 2 (failed callback) and the _deferReds array length is 0, a warning is given */
  if (self._state === 2 && self._deferreds.length === 0) {
    /** * Call the Promise constructor's _immediateFn method * parameter fn: the warning method to execute */
    Promise._immediateFn(function () {
      /* If it is not processed, a warning is given */
      if(! self._handled) {/** * Calls the._unhandledrejectionfn method of the Promise constructor with the argument self._value: rejection reason */
        Promise._unhandledRejectionFn(self._value)
      }
    })
  }
}
Copy the code
  • If it is a failure callback (rejected term), and_deferredsIf the array length is 0, a warning is given
  • _deferredsThe array length is determined byPromise.reject()Is there anything in the backcatchDecided, see follow-up

Browser warning – Phase testing

new Promise((resolve, reject) = > {
  reject(2) // Possible Unhandled Promise Rejection: 2
})
Promise.reject(3) // Possible Unhandled Promise Rejection: 3
Promise.resolve(Promise.reject(4)) // Possible Unhandled Promise Rejection: 4
Promise.reject(Promise.reject(5)) // Possible Unhandled Promise Rejection: Promise { _state: 2, _handled: false, _value: 5, _deferreds: [] }
Copy the code

Summary of Implementation results

  • Promise.resolveandPromise.rejectrightnew PromiseOn the basis of encapsulation
  • Promise.resolveIf the parameter is an expiration, the expiration is returned
  • Failed callbacks are temporarily warned in the browser

As of the code in this section →