This is the 11th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021

If you feel helpful, please click πŸ‘ to encourage you

preface

You probably use Promise a lot, right? But do you know where your Promise came from? Do you know what the Promise follows?

There are many Promise specifications, such as Promise/A, Promise/B, Promise/D and the upgraded version of Promise/A, Promise/A+. The Promise/A+ specification is used in ES6.

So today we’re going to talk about the Promise/A+ specification.

Any object or function that conforms to the Promise specification can be A Promise. The Promise we use is just one form of the Promise/A+ specification. You can also encapsulate A function that conforms to the specification, so you can write A function that is also called A Promise.

The term

  • Promise (instance) :Is athenMethod that behaves according to this specification.
  • Thenable (with then method) :It’s a definitionthenThe object or function of a method.
  • Value:It’s arbitrary and legalJavascriptValue, (includesundefined.thenable , promise).
  • Exception:Is the use ofthrowThe value thrown by the statement.
  • There is no reason for this.Is saidpromiseWhy isrejectedThe reason is tothrowaerror.

requirements

The state of the Promise

The current state of a Promise must be one of the following three states: Pending, Fulfilled and Rejected.

  • In the wait state,PromiseThe following conditions must be met: Can be changedHas been completed ζˆ– Has refused to 。
  • In the finished state,PromiseThe following conditions must be met:
    • Cannot migrate to any other state
    • Must have an immutable value
  • In the case of a refusal,PromiseThe following conditions must be met:
    • Cannot migrate to any other state
    • There must be an immutable cause

There must be a then method

A Promise must provide a THEN method to access its current value and reason. That is, when a Promise’s state changes from waiting to completed or rejected, there has to be a place to register the callback function.

  • The Promise’s then method accepts two optional parameters, Promise.then(ondepressing, onRejected), the two parameters must be functions. If they are not, they need to be ignored.

  • onFulfilled

    • whenPromiseWhen the execution is complete,onFulfilledMust be called, whose first argument isPromiseThe value of the.
    • inPromiseAt the end of execution,onFulfilledCannot be called.
    • onFulfilledCannot be called more than once.
  • onRejected

    • whenPromiseHaving been denied enforcement,onRejectedMust be called, whose first argument isPromiseThe reason why.
    • inPromiseBefore being denied enforcement,onRejectedCannot be called.
    • onRejectedCannot be called more than once.
  • Ondepressing and onRejected must not be called until the implementation context stack contains only the platform code. This is related to the Event Loop in JavaScript. OnFulfilled and onRejected cannot be implemented before the synchronized code is completed.

  • Ondepressing and onRejected must be called as normal functions (i.e., non-instantiated new Function, so that inside the Function this points to the window in non-strict mode).

  • The then method can be called multiple times by the same Promise:

    • whenPromiseWhen successfully executed, allonFulfilledCallbacks must be made in the order in which they were registered.
    • whenPromiseWhen rejected, allonRejectedCallbacks must be made in the order in which they were registered.
  • The then method must return a Promise object, promise2 = promise1. Then (onFulfilled, onRejected)

    • Promise2 will enter the onFulfilled state as long as onFulfilled or onRejected returns a value x.

    • If onFulfilled or onRejected throws an exception E, then promise2 must be rejected and return E as the reason.

    • If ondepressing is not a function, and promise1 has completed, promise2 must execute successfully and return the same value.

    • If onRejected is not a function and promise1 has been rejected, promise2 must perform the reject callback and return the same reject.

    • Let’s look at an example.

 const promise1 = new Promise((resolve, reject) = > reject())
 // Reject is manually called as rejected, and the callback function of the second parameter is executed. Back to 123.
 promise1
   // As long as' ondepressing 'or' onRejected 'returns a value' x ', 'promise2' will enter the 'ondepressing' state, which is 123.
   .then(null.() = > {
     return 123
   })
   //- According to which if 'ondepressing' is not a function and 'promise1' has been completed, 'promise2' must be successfully executed and return the same value. The value is still 123.
   .then(null.null)
   // Same value as above: 123.
   .then(null.null)
   // According to which if 'ondepressing' is not a function and 'promise1' has completed, 'promise2' must be successfully executed and return the same value. Printing promise2 completed,123
   .then(
     (res) = > { console.log('Promise2 completed', res) },  //=> Promise2 completes 123
     (res) = > { console.log('Promise2 has been rejected', res) }
   )
Copy the code

Promise’s resolution process

The Promise resolver is an abstract operation that we represent as [[Resolve]](Promise, x), which takes a Promise and a value as input. (This means to set the promise state to resolve and pass x as the value).

  promise.then((x) = > {
    console.log("Will execute this function and pass in the value of the x variable.", x);
  });
Copy the code

If X has a then method and looks like a Promise, the resolver tries to make the Promise accept the state of X, otherwise it implements the Promise with the value of X.

ifPromise ε’Œ xThey all point to the same object

Reject a Promise as TypeError rejection. This is not implemented, if there are big guys know how to return a responsibility, please comment on it.

ifx δΈΊ Promise, then makePromiseacceptxThe status of:

If X is in wait state, the Promise needs to remain in wait state until x is executed or rejected.

  const promise1 = new Promise((resolve, reject) = > {
    setInterval(() = > {
      resolve('Done')},3000)})const promise2 = new Promise((resolve, reject) = > resolve(promise1))
  promise2.then(
    (val) = > {
      console.log(val); // the output is complete after 3000ms
    },
    (val) = > {
      console.log(val); })Copy the code

If x is in the completed state, execute the Promise with the same value.

  const promise1 = new Promise((resolve, reject) = > resolve('Done'))
  const promise2 = new Promise((resolve, reject) = > resolve(promise1))
  promise2.then(
    (val) = > {
      console.log(val); // The output is complete
    },
    (val) = > {
      console.log(val); })Copy the code

If X is in the rejected state, reject the Promise with the same grounds.

  const promise1 = new Promise((resolve, reject) = > reject('Rejected'))
  const promise2 = new Promise((resolve, reject) = > resolve(promise1))
  promise2.then(
    (val) = > {
      console.log(val);
    },
    (val) = > {
      console.log(val);// The output was rejected})Copy the code

ifxIs an object or function

1. Execute the command firstx.then.

  const promise = new Promise((resolve, reject) = > resolve({
    then: () = > console.log('hello,promise') //=> hello,promise
  }))
  promise.then((x) = > {
    // First try executing 'x.hen', printing hello,promise.
  })
Copy the code

2. If you takex.thenThrows an error when the value ofe, theeRefusal on grounds of proofPromise 。

  const promise = new Promise((resolve, reject) = > resolve({
    get then() {
      throw Error("I will refuse.") // error
    }
  }))
  promise.then(
    (val) = > {
      console.log(val);
    },
    (val) = > {
      console.log(val); //=> error I want to reject})Copy the code

3. IfthenIs not a function of thetaxFor the parameter will bePromiseChanges to the completed state.

  const promise = new Promise((resolve, reject) = > resolve({
    name: 'warbler'
  }))
  promise.then(
    (val) = > {
      console.log(val.name); //=> warbler
    },
    (val) = > {
      console.log(val); })Copy the code

4. Ifx.thenIs the function,

Call x as the function’s scope this. Pass two callback functions as arguments, the first called resolvePromise and the second called rejectPromise.

4.1 ifresolvePromiseIn order to valueyRun when called for parameters[[Resolve]](promise, y)

  const promise = new Promise((resolve, reject) = > resolve({
    then: (resolvePromise, rejectPromise) = > {
      resolvePromise('Done')
    }
  }))
  promise.then(
    (val) = > {
      console.log(val); / / = > has been completed
    },
    (val) = > {
      console.log(val); })Copy the code

4.2 ifrejectPromiseTo according to therIs called with an argument, then with an argumentrRefused topromise

  const promise = new Promise((resolve, reject) = > resolve({
    then: (resolvePromise, rejectPromise) = > {
      rejectPromise('Rejected')
    }
  }))
  promise.then(
    (val) = > {
      console.log(val);
    },
    (val) = > {
      console.log(val); / / = > has been rejected})Copy the code

4.3 ifresolvePromise ε’Œ rejectPromiseAre called, or are called more than once by the same parameter, the first call takes precedence and the rest are ignored

  const promise1 = new Promise((resolve, reject) = > resolve({
    then: (resolvePromise, rejectPromise) = > {
      resolvePromise('Done')  / / to take effect
      resolvePromise('Done') / / ignore
      rejectPromise('Rejected') / / ignore
    }
  }))
  promise1.then(
    (val) = > {
      console.log(val); / / = > has been completed
    },
    (val) = > {
      console.log(val); })Copy the code

4.4 How To CallthenMethod throws an exceptione:

If either the resolvePromise or rejectPromise has already been invoked, it is ignored.

  const promise = new Promise((resolve, reject) = > resolve({
    then: (resolvePromise, rejectPromise) = > {
      resolvePromise('Done')
      throw new Error("I will refuse.") / / ignore
    }
  }))
  promise.then(
    (val) = > {
      console.log(val); / / = > has been completed
    },
    (val) = > {
      console.log(val); })Copy the code

Otherwise, reject the promise based on e.

  const promise = new Promise((resolve, reject) = > resolve({
    then: (resolvePromise, rejectPromise) = > {
      throw new Error("I will refuse.")
    }
  }))
  promise.then(
    (val) = > {
      console.log(val);
    },
    (val) = > {
      console.log(val); //=> error I want to reject})Copy the code

ifxIs not an object or a functionxFor the parameter will bePromiseChanges to the completed state.

  const promise = new Promise((resolve, reject) = > resolve('warbler'))
  promise.then(
    (val) = > {
      console.log(val); //=> warbler
    },
    (val) = > {
      console.log(val); })Copy the code

After the language

At this point the Promise/A+ specification is resolved, and the next task is to write the Promise by hand.

reference

Promises/A+

PromiseA + specification details