Synchronous mode and asynchronous mode
Event loops and message queues
Several ways of asynchronous programming
- Callback function - Promise - Promise is an object, The then methods used to indicate whether an asynchronous task eventually succeeds or fails (either success or failure will result in a callback) - the Promise object will return a brand new Promise object - the later THEN methods register the callback for the Promise returned by the previous THEN - The return value of the callback from the previous THEN method is used as an argument to the callback from the later THEN method - if the callback returns a Promise, The callback to the then method will wait for its completion - promise.all () waits for all tasks to complete - promise.race () will only wait for the first task to completeCopy the code
Promise asynchronous schemes, macro/micro task queues
- The task in the callback queue is called ** macro task ** - The macro task can be executed with some additional requirements temporarily, can choose to queue as a new macro task, or can be used as the ** micro task of the current task ** - micro task: Execute immediately after the current task ends - the Promise callback is executed as a microtask - mutationobserve-process.nexttickCopy the code
Generator asynchronous scheme, Async/Await syntax sugar
Write a Promise
All instance function p1() {return new Promise((resolve, reject) => {setTimeout(() => {resolve(‘p1’)}, 2000)})}
function p2() { return new Promise((resolve, reject) => { setTimeout(() => { resolve(‘p2’) }) }) } Promise.all([‘a’, ‘b’, p1(), p2(), ‘c’]).then(result => { // result -> [‘a’,’b’,’p1′,’p2′,’c’] }) `
Write a Promise
Promise = fulfilled fulfilled pending pending -> funlfilled pending -> Fulfilled fulfilled pending -> fulfilled fulfilled pending -> fulfilled fulfilled pending -> fulfilled fulfilled pending -> fulfilled fulfilled pending Once the state is determined, it cannot be changed. 3. Resolve and reject are used to change the state There is one parameter that indicates the cause of the failure 6. The then methods can be called multiple times on the same Promise object. */ / const PENDING = ‘PENDING’ // const FULFILLED = ‘FULFILLED’ // successful const REJECTED = ‘FULFILLED = ‘rejected’ // fail
class MyPromise() { try { constructor(executor) { executor(this.resolve, This. Reject)}} Catch (e) {this.reject(e)} // Promise status status = PENDING // Value = undefined // Reason = Undefined // successCallback = [] // failCallback = [] resolve = value => {// If the status is not waiting to prevent the program from executing down if (this.status ! This. Status = this. Value = value // Determine whether the successful callback exists. Call while (enclosing successCallback. Length) enclosing successCallback. The shift () ()} reject = “reason = > {/ / if the status is not waiting to stop program execution down the if (this.status ! This. Reason = Reason while (this.failback.length) this. Staus = REJECTED // This. this.failCallback.shift()() } then(successCallback, failCallback) { successCallback = successCallback ? successCallback : value => value; failCallback = failCallback ? failCallback : reason => { throw reason } let promise2 = new MyPromise((resolve, This is very depressing. (forget) {setTimeout(() => {try {let x = successCallback(this.value)) // Determine whether x is a normal value or a promise object. // If it is a normal value, call resolve. // If it is a promise object, look at the result returned by the Promise object resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0) } else if (this.status === REJECTED) { setTimeout(() => { try { let x = failCallback(this.reason) // Determine whether x is a normal value or a promise object. // If it is a normal value, call resolve. // If it is a promise object, look at the result returned by the Promise object resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0) } else { this.successCallback.push(() => { setTimeout(() => { try { let x = successCallback(this.value) // Determine whether x is a normal value or a promise object. // If it is a normal value, call resolve. // If it is a promise object, look at the result returned by the Promise object resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0)}) this.failback.push (() => {setTimeout(() => {try {let x = failCallback(this.reason) // If it is a normal value, call resolve directly. // If it is a Promise object, look at the result returned by the Promise object and decide whether to call resolve or reject based on the result returned by the promise object resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0) }) } }) return promise2 }
Finally (callback) {return this.then(value => {// callback() // return value return MyPromise.resolve(callback()).then(() => value) }, () => { // callback() // throw reason return MyPromise.resolve(callback()).then(() => { throw reason }) }) } catch (failCallback) { this.then(undefined, failCallback) } static all(array) { let result = [] let index = 0 return new MyPromise((resolve, reject) => { function addData(key, value) { result[key] = value index++ if (index === array.length) { resolve(result) } } for (let i = 0; i < array.length; I ++) {let current = array[I] if (current instanceof MyPromise) {// Then (value => addData(I, value), Reason => reject(reason))} else {// addData(I, array[i]) } } }) } static resolve(value) { if (value instanceof MyPromise) return value return new MyPromise(resolve => resolve(value)) }Copy the code
}
function resolvePromise(x, resolve, reject) { if (promise2 === x) { return reject(new TypeError(‘Chaning cycle detected for promise #’)) } if (x instanceof MyPromise) {// promise object // x.hen (value=>resolve(value),reason=>reject(reason)) x.hen (resolve, Reject)} else {// resolve(x)}}
module.exports = MyPromise
`