When you instantiate a Promise, the resolve method passes in three arguments:

  1. The current Promise object itself is passed in as an argument
  2. Pass in a simple data type value such as String, Boolean, number, and so on
  3. Pass in an object or function

Resolve method

function resolve (self, newValue) {
    // Pass itself as a parameter to resolve in the instantiation, call reject, and set state to 2
    if (newValue === self) {
        return reject(self,
            new TypeError('A promise cannot be resolved with itself'))}// Pass a Promise object or function as an argument
    if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
        var then = getThen(newValue)
        // If newValue is a Promise object, set state to 3 and value to the incoming Promise object
        if (then === self.then && newValue instanceof Promise) {
            self._state = 3
            self._value = newValue
            final(self)
            return
        } else if (typeof then === 'function') {
            doResolve(then.bind(newValue), self)
            return}}// The value of newValue is a simple data type that prints the value directly and changes the state to 1
    self._state = 1
    self._value = newValue
    final(self)
}
Copy the code

The argument is the current Promise object itself

When the current Promise object itself is passed to the resolve method as an argument, the resolve internal handler throws A type error: A promise cannot be resolved with itself. The code:

let promise = new Promise(function (resolve, reject) {
    setTimeout(function () {
        resolve(promise)
    })
})
Copy the code

Then run the debugger in the doResolve method:

As you can see from the debugger, after passing the current Promise object itself as an argument, resolve does a comparison between newValue and self that results in true, so the program refuses to proceed and throws a type error.

Pass in a simple data type

When a simple data type value is passed to resolve during instantiation, state is set to 1 and value is set to newValue, and the program execution is completed and the result is output.

Pass in an object or function

  • Passing in an object

    When instantiating an incoming object, first use getThen method to process newValue, add then attribute to newValue, getThen source code:

    function getThen(obj) {
        try {
            return obj.then
        } catch (ex) {
            LAST_ERROR = ex
            return IS_ERROR
        }
    }
    Copy the code

    Then === self.then = true; then == self.then If true, use newValue instanceof Promise to determine if the incoming newValue is a Promise object. Once these two conditions are met, set state to 3 and value to the incoming newValue, which is the incoming Promise object. Chestnut code:

    let promise2 = new Promise(function (resolve, reject) {
        resolve('Incoming Promise object')})let promise = new Promise(function (resolve, reject) {
        resolve(promise2)
    }).then(res= > {
        console.log(res) // The promise object passed in
    })
    Copy the code

    After the execution of Resolve, the invocation of then, the promise prototype method, is actually translated into a series of executions of the Promise2 instance when handle executes. What does Handle do? The code is as follows:

    function handle (self, deferred) {
        // If the current execution state is 3, convert the current promsie object to the incoming Promise object
        while(self._state === 3) {
            self = self._value
        }
        if (self._state === 0) {...return
        }
        handleResolve(self, deferred)
    }
    Copy the code

    As you can see from the handle code, when state is 3, the current promise object is set to the incoming promise object. The then method of instance Promise outputs the result of instance promise2.

  • Passing in a function

    When a function is passed in, the value of then is undefined in the getThen method. **typeof then === ‘function’** set state to 1, value to newValue and then to false. Chestnut code:

    let promise = new Promise(function (resolve, reject) {
        resolve(function () {})
    }).then(res= > {
        console.log(res) // f () {}
    })
    Copy the code