Promise use

Promise use

Promise benefits

  1. Chain structure, easy to read
  2. Solve the hell callback problem

Basic operation of promise

//random function function rand ( m, n ) { return Math .ceil( Math .random()*(n-m + 1 ) + m- 1 ); } //Use new to create a Promise const p = new Promise ( ( resolve, reject ) => { //Promise receives a function type parameter value, this function also has two formal parameters, the first is called when the asynchronous task succeeds, the first The two are called when it fails (the resolve and reject names are arbitrarily chosen, only related to the location) //Asynchronous operation let n = rand( 1 , 100 ); if (n< 30 ){ resolve(n); //After use, you can set the status of Promise to success (that is, the status of p), and you can pass a successful result to resolve } else { reject(n); //After use, you can set the status of Promise to failure (that is, the status of p), and you can pass a reason for failure to reject //Here are all incoming n } }) //then receives two parameters, //if p is in a successful state, the first function is called (that is, the function called when the asynchronous is successful), //if p is in a failed state, the second function is called (that is, when the asynchronous fails Function) //These two functions have a formal parameter, which is the value passed in by resolve and reject (the value name can be chosen ) p.then( ( value )=> { console .log( 'You won! The number is' + value) }, ( value )=> { console .log( 'I almost won the prize!!! Your number is' + value) }) Copy code

fs read file

const fs = require ( 'fs' ) //Callback function form //fs.readFile('url/txt', (err, data)=>{ //if(err) throw err; //console.log(data.toString()) //}) //Promise form let p = new Promise ( ( resolve, reject )=> { fs.readFile( 'url' , ( err, data )=> { if (err) { reject(err) } else { resolve(data); } }) }) p.then( value => { console .log(value.toString()) }, reason => { console .log(reason.toString()) }) Copy code

ajax

Copy code

util.promisify()

const util = require ( 'util' ) const fs = require ( 'fs' ) let myReadFile = util.promisify(fs.readFile) myReadFile( './book.txt' ).then( value => { console .log(value.toString()) }, reaason => { console .log(reason) }) Copy code

Encapsulate ajax request

Promise state changes

As mentioned earlier, resolve() and reject() can change the state of the promise. This state is actually an attribute in the promise instance object (PromiseState) pending default value resolved/fulfilled succeeded rejected failed

PromiseState can only be changed once, and can only be changed from pending to resolved or pending to rejected

Introduction to the result value property of the promise object

  1. PromiseResult

What is saved is the result of the success/failure of the object. resolve() or reject() can change this value, that is, the n of resolve(n)

promise process

new Promise() 1. Success: resolve promise object (resolved state) then() callback onResolved() new promise object

2. Failure: reject promise object (rejected state) then() callback onRejected() New promise object Copy code

API

  1. Promise constructor: Promise(excutor)()

excutor will be executed immediately without entering the queue to wait for execution, that is, synchronous call

  1. Promise.prototype.then method: (onResolved, onRejected)=>()

Specify the success callback used to get the value and the failure callback used to get the failure reason to return a new promise object

  1. Promise.prototype.catch method: (onRejected)=>()

Can only be used for failed callbacks

let p = new Promise ( ( resolve, reject )=> { reject( 'something error' ) }); p.catch( reason => { console .log(reason) }) Copy code

catch is shorthand for then(null, ()=>())

  1. Promise.resolve:(value)=>{}
let p = Promise .resolve(something) //If the passed parameter something is a non-promise type object, the returned result is a successful promise object, that is, p is resolved or fulfilled, and its PromiseResult is something //if passed in promise for the object type, the p-PromiseState PromiseState the promise and passed the same parameters of the object something something, PromiseResult same duplicated code
  1. Promise.reject()

Return a Promise object, the result is rejected, regardless of whether the incoming Promise object or ordinary data

let p1 = Promise .reject( 'p1 is rejected' ) let p = new Promise ( ( resolve, reject ) => { resolve( 'p is success' ) }) let p2 = Promise .reject(p) Console .log (P1) //Rejected 'Rejected IS P1' Console .log (P2) //Rejected Promise (P) copying the code
  1. Promise.all()

Receive an array of Promise objects, and the return result is the AND operation of the results of these Promise objects, that is, if all resolved, the return result is resolved, otherwise it is rejected. If the return result is resolved/fulfilled, the returned PromiseResult is also an array. It is the PromiseResult of these Promise objects that are spliced together. If the return result is rejected, then the PromiseResult of the wrong Promise object in the array is returned.

let p1 = Promise .resolve( 'ok p1' ) let p2 = Promise .resolve( 'ok p2' ) let p3 = Promise .resolve( 'ok p3' ) let p4 = Promise .reject( 'false p4' ) let result1 = Promise .all([p1, p2, p3]) let result2 = Promise .all([p1, p2, p4]) console .log(result1) //resolved Array(3)['ok p1','ok p2','okp3'] console .log(result2) //rejected false p4 Copy code
  1. Promise.race()

Pass in an array of Promise objects, and return the PromiseState and PromiseResult of the first Promise object that changes state

let p1 = Promise .resolve( 'ok p1' ) let p2 = Promise .resolve( 'ok p2' ) let p3 = Promise .resolve( 'ok p3' ) let p4 = new Promise ( ( resolve, reject )=> { setTimeout ( () => { resolve() }, 1000 ); }) let result1 = Promise .race([p1, p2, p3]) console .log(result1) //resolved'ok p1' let result2 = Promise .race([p4, p1, p2, p3]) console .log(result2) //resolved'ok p1' Copy code

The way to change the state of the Promise object

  1. resolved()

  2. rejected()

  3. Throws an error

the let P = new new Promise ( ( Resolve, Reject ) => { the throw 'something Wrong' }) console .log(p) //rejected'something wrong' Copy code

When a Promise has multiple thens, are they all executed?

When the state of Promise changes to resolve, the corresponding resolve will be executed, and reject is the same

let p1 = new Promise ( ( resolve, reject ) => { }) //Neither of the following will execute p1.then( value => { console .log(value + '1' ) }) p1.then( value => { console .log(value + '2' ) }) let p2 = new Promise ( ( resolve, reject ) => { resolve() }) //Both of the following execute p2.then( value => { console .log(value + '1' ) }) p2.then( value => { console .log(value + '2' ) }) let p3 = new Promise ( ( resolve, reject ) => { resolve() }) //Execute p3.then( value => { console .log(value + '1' ) }) //Do not execute p3.then( null , value => { console .log(value + '2' ) }) Copy code

Change the state of the Promise and specify the callback function

That is, resolve/reject or then execute first

Both situations can also happen

  1. resolve()/reject() first, then() after
let p = new Promise ( ( resolve, reject ) => { //When this is a synchronous task, resolve()/reject() is executed first, and then the callback function is executed resolve(); }) p.then( value => {}, reason => {}) Copy code
  1. then() is executed first, and then resolve()/reject() is executed to change the state
let p = new Promise ( ( resolve, reject ) => { //When this is an asynchronous task, first execute then() and compile and then call resolve()/reject() to change the state setTimeout ( function () { resolve(); }, 3000 ) }) p.then( value => {}, reason => {}) Copy code
  1. Description

There are only two cases in the above two situations. In fact, it depends on who is executed first. Whoever executes first will be the first. It may be that resolve() is executed after asynchronous operation, but then() may also be in a setTimeout, which is better than asynchronous. resolve() will be executed later. At this time, resolve()/reject() is executed first, and then then() is executed.

The return result of the then method

The then method returns a Promise object, the result of which is affected by the two functions inside

  1. Throws an error
let p = new Promise ( ( resolve, reject )=> { resolve( 'ok' ) }) the let Result = p.then ( value => { the throw 'something error' }, reason => { console .log(reason) }) console .log(result) //PromiseState: rejected, PromiseResult: something error (that is, the error thrown) Copy code
  1. The return result is a non-Promise object
let p = new Promise ( ( resolve, reject )=> { resolve( 'ok' ) }) the let Result = p.then ( value => { return 'something' }, reason => { Console .log (reason) }) console .log(result) //PromiseState: fulfilled, PromiseResult: something (that is, the result is returned) Copy code
  1. Return Promise object
let p = new Promise ( ( resolve, reject )=> { resolve( 'ok' ) }) let result = p.then( value => { return new Promise ( ( resolve, reject ) => { resolve( 'something' ) }) }, reason => { console .log(reason) }) console .log(result) //PromiseState: fulfilled, PromiseResult: something //The state is the same as that of the Promise object returned, and the PromiseResult is the same as the PromiseResult that returns the Promise object. Copy code
  1. Nothing
let p = new Promise ( ( resolve, reject ) => { resolve( 'ok' ) }) let result = p.then( value => { console .log(value) }, reason => {}) console .log(result) //PromiseState:fulfilled, PromiseResult:undefined Copy code
  1. note

The then method returns a new Promise object

let p = new Promise ( ( resolve, reject ) => { resolve( 'ok' ) }) let result = p.then( value => { console .log(value) }, reason => {}) console .log(result) //PromiseState:fulfilled, PromiseResult:undefined console .log(p) //PromiseState:fulfilled, PromiseResult:ok //The two Promises are not the same Copy code

Concatenate multiple tasks

let p = new Promise ( ( resolve, reject ) => { setTimeout ( ()=> { resolve( 'ok' ); }, 2000 ) }); p.then( value => { return new Promise ( ( resolve, reject )=> { resolve( 'right' ); }); }).then( value => { console .log(value) }) Copy code

Abnormal penetration

let p = new Promise ( ( resolve, reject ) => { setTimeout ( ()=> { resolve( 'ok' ); }, 2000 ) }); p.then( value => { console .log( 111 ) }).then( value => { console .log( 222 ) }).then( value => { console .log( 333 ) }).catch( reason => { console .log(reason) }) //If there is an error in the above, the last catch will be called Copy code

Interrupt the Promise chain

When there is a chain like .then.then that penetrates abnormally above, sometimes I don t want to continue executing the following chain if a certain condition is reached or the normal execution is completed. At this time, the Promise chain needs to be terminated.

let p = new Promise ( ( resolve, reject ) => { setTimeout ( ()=> { resolve( 'ok' ); }, 2000 ) }); p.then( value => { console .log( 111 ) //If you interrupt here return new Promise ( ()=> {}) //In fact, it returns a Promise object with pending status//If it is pending, that is, the status has not changed, then then will not be executed () or catch(), etc., is the only way to interrupt the Promise chain }).then( value => { console .log( 222 ) }).then( value => { console .log( 333 ) }).catch( reason => { console .log(reason) }) Copy code

Why can't I send it?