preface

Promises are an asynchronous solution, and without promises, asynchronous solutions are callback functions, and too much nesting can lead to callback hell. The following is intended to cover core usage and implementation.

1. Then I promise

` `

  1. thenThe first argument to the method isresolvedThe state callback function, the second argument (optional) isrejectedState callback function.
  2. thenMethod returns a new onePromiseInstance (note, not the original onePromiseInstance). So we can use the chain notation, which is 1, 2, 3thenMethod is followed by another callthenMethods.
  3. The value returned by the then callback is passed as an argument to the resolve of the Promise instance returned by the THEN method
  4. Use chain typethen, you can specify a set of callback functions to be called in order. In this case, the previous callback may still return onePromiseObject (that is, there is an asynchronous operation), in which case the latter callback will wait for thatPromiseThe object is called only when its state changes.
  5. If a Promise returns reject, then is not executed and goes into a catch

` `

Then --demo1-- new Promise((resolve, reject) => {resolve(100); }). Then (data => {console.log(data); // 100 return 'adf' // then method returns a new Promise instance, meaning that even without a return value, }). Then (data => {console.log(data) // Function wait(ms = 1000, data) {// Return a Promise, Resolve (data) return new Promise((resolve, reject) => { setTimeout(() => { resolve(data) },ms) }) } const promise = new Promise((resolve, reject) => { resolve(100); }).then(data => { console.log(data); // 100 return wait(2000, 'qwe'); }) .then(data => { console.log(data); // 2 SEC later qwe}) const promise = new promise ((resolve, resolve) reject) => { reject('some error') }).then(data => { console.log(data); Catch (e => {console.log(e) // some error})Copy the code

2, async await syntax sugar

Async in front of the function returns a Promise object, so you can use the then syntax

// async-- function wait(ms = 1000, data) {// Return a Promise, Resolve (data) return new Promise((resolve, reject) => { setTimeout(() => { resolve(data) },ms) }) } async function foo(){ console.log('begin'); const w1 = await wait(1000, 'w1'); console.log('target1'); const w2 = await wait(2000, 'w2'); console.log('target2'); } foo().then(data => {console.log('finished', data) // data is undefined.Copy the code

Reject occurs in async, which is the same as reject in the Promise. If there is a catch, it will catch, and if there is no catch, it will throw an error

Function wait(ms = 1000, data) {// Return a Promise, Resolve (data) return new Promise((resolve, reject) => { setTimeout(() => { resolve(data) },ms) }) } async function bar(){ console.log('begin'); const w1 = await wait(1000, 'w1'); console.log('target1'); const w2 = await wait(2000, 'w2'); const x = await Promise.reject('some error'); } bar().then(d => console.log(d)); // Error bar().catch(e => console.log(e)); Error async function bar(){try{console.log('begin'); const w1 = await wait(1000, 'w1'); console.log('target1'); const w2 = await wait(2000, 'w2'); const x = Promise.reject('some error'); } catch(ex) {console.log(ex, 'js catch syntax can also catch ')}}Copy the code

Concurrency and competition

Function wait(ms = 1000, data) {return new Promise((resolve, resolve) reject) => { setTimeout(() => { resolve(data); }, ms)})} // Promise. Promise.all([wait(2000, 1), wait(3000,2)]).then(data => {console.log(data); // [1,2]}) // promise. race([wait(2000, 1), wait(3000, 2)]).then(data => { console.log(data) // })Copy the code

4. Promise core implementation

Const PENDING = 1; const PENDING = 1; const FULFILLED = 2; const REJETED = 3; class myPromise { constructor(excutor) { this.state = PENDING; // This resolver is always executed in an asynchronous function, Const resolver = (value) => {if(this.state === PENDING) {this.value = value; // This. Value this. State = depressing; } // A Pending state is stored in the array. This will be a big pity (fulfilled) {const x = onfill (fulfilled); // If x is also a Promise, it needs to be improved. Resolve is just fulfilles in the loop, and there's just one element of fulfilles at present, and just one of fulfilles all the time, // because even with.then().then().then(), Each execution of resove in then continues the item after. Then, and at //. Then, like now, the current loop has been completed. resolve(x); } } const rejector = (value) => { } excutor(resolver, rejector); Fulfills = []; fulfills = []; fulfills = []; // this will be a big pity. // This will be a big pity. // Return a new Promsie switch(this.state) {case depressing: const x = ondepressing (this.value); // Implement the ondepressing method, which is passed in externally. Value: resolve(x); // Perform resolve on the Promise returned by THEN and pass in x, which is the return value break of ondepressing; // This. Fulfills. Push ([onFulfilled, resolve]); // Enter the array break; }} new myPromise((resolve, reject) => {setTimeout(() => {// resolve(200) //}, 1000) resolve(100); This. value return 'ABC' // Then after the value of this return is not received, }). Then (data => {// The entry is this.value console.log(data); }). Then (d => console.log(d)) // SDFCopy the code

5. Main function realization of Promise

Promise A+ specification requirements

/* / const statusMap = {PENDING: 'PENDING ', FULFULLED: 'fulfilled', REJECTED: Ledpromise (promise, value) {if (promise.status!) {if (promise.status! == statusMap.PENDING) { return } promise.value = value; // This will be a pity; // This will be a pity; // This will be a pity; // Change the state runCbs(promise.vars, value); // change the state runCbs(promise.vars, value); } function rejectedPromise(promise, reason) {if (this.status! == statusMap.PENDING) { return } promise.value = reason promise.status = statusMap.REJECTED; runCbs(promise.rejectedCbs, reason); } function runCbs(cbs, value) { cbs.forEach(cb => cb(value)) } function isFunc(fn) { return ( Object.prototype.toString.call(fn).toLowerCase() === '[object function]' ); } function isPromise(p) { return p instanceof ourPromise; } function isObject(obj) { return ( Object.prototype.toString.call(obj).toLowerCase() === '[object object]' ); Function resolvePromise(resolvePromise, If (promise === x) {rejectedPromise(promise, new TypeError(' Cant be the same')); This is a big pity; // x isPromise if (isPromise(x)) {if (x.status === statusMap.FUlFILLED promise (promise, x.value); return } if (x.status === statusMap.REJECTED) { rejectedPromise(promise, x.reason); return; } if (x.status === statusMap.PENDING) { x.then(() => { fulfilledPromise(promise, x.value); }, () => { rejectedPromise(promise, x.reason); }); return; }} / / if x is the object or function (isObject (x) | | isFunc (x)) {let then; let called = false; try { then = x.then; } catch (errot) { rejectedPromise(promise, error); If (isFunc(then)) {return (isFunc(then)) {return (isFunc(then)) { Then. Call (x, (y) => {if (called) {return} called = true; resolvePromise(promise, y); }, (r) => { if (called) { return } called = true; rejectedPromise(promise, r) }); } catch (e) { if (called) { return } called = true; rejectedPromise(promise, e) } } else { fulfilledPromise(promise, x); return; Ledpromise (promise, x); ledPromise(promise, x); } } class ourPromise { constructor(fn) { this.status = statusMap.PENDING; // Pending this.value = undefined; // This. Reason = undefined; // Failure cause this. this = []; this.rejectedCbs = []; Ledpromise (this, value); fn((value) => {ledPromise(this, value); }, (reason) => {rejectedPromise(this, reason); }); } then(onFulfilled, onRejected){ const promise1 = this; // This is a big promise; // This is a big promise; // Save a current promise instance const promise2 = new ourPromise(() => {} This is a big pity) {// If the parameter of then is not a function, then ignore it and return promise1 if (! IsFunc (ondepressing)) {return promise1} SetTimeout (() => {try {const x = ondepressing (promise1. Value); resolvePromise(promise2, x); } catch (e) {rejectedPromise(promise2, e); If (promise1. Status === statusmap. Rejected) {if (promise1. Status === statusMap. Rejected) { IsFunc (onRejected)) {return promise1} SetTimeout (() => {try {const x = onRejected(promise1.value); resolvePromise(promise2, x); } catch (e) {rejectedPromise(promise2, e); Status === = statusmap.pending) {ondepressing = isFunc(ondepressing)? onFulfilled : (value) => value; onRejected = isFunc(onRejected) ? onRejected : (err) => {throw err}; promise1.fulfilledCbs.push( () => { setTimeout(() => { try { const x = onFulfilled(promise1.value); resolvePromise(promise2, x); } catch (e) {rejectedPromise(promise2, e); }}, 0)}); promise1.rejectedCbs.push( () => { setTimeout(() => { try { const x = onRejected(promise1.reason); resolvePromise(promise2, x); } catch (e) {rejectedPromise(promise2, e); }}, 0); }); // test function wait (ms = 1000, data) {return new promise ((resolve, resolve)) rejected) => { setTimeout(() => { resolve(data) }, 0) }) } const promise1 = new ourPromise((resolve, rejected) => { console.log('start') resolve(122); }). Then (data => {console.log(data) return wait(1000, 'ha ha ha ')}). Then (d => console.log(d,' DDDD ')).Copy the code

6, summary

Simply put, there are two main pieces of Promise

  • Implementation of then,thenMethod returns a new onePromiseThe instance
  • A resolution state resolvePromise