当前位置:网站首页>Hard core parsing promise object (do you know these seven common APIs and seven key questions?)

Hard core parsing promise object (do you know these seven common APIs and seven key questions?)

2022-04-23 18:13:00 Xiaojie learning front end

Catalog

One 、Promise To understand and use

Promise The concept of

Promise Use

Back to hell

Solution

Promise The basic usage of

Promise Initial experience of practice

fs Module read file

Use promise encapsulation ajax Asynchronous requests

promise Object state properties

promise Object result value property

Small cases

Two 、Promise API

Promise Constructors : Promise (excutor) {}

Promise.prototype.then()

Promise.prototype.catch()

Promise.resolve() 

Promise.reject()  

Promise.all()    

Promise.race() 

3、 ... and 、Promise key problem  

1. How to modify the state of an object

2. Whether multiple callbacks can be executed

3. The sequence of changing state and executing callback

4.then What determines the result returned by the method  

5. Concatenate multiple tasks

6. extraordinary transmission

7. How to terminate Promise chain  


One 、Promise To understand and use

Promise The concept of

Promise Is a solution to asynchronous programming , And what was our previous solution ? you 're right , It's a callback function .Promise More reasonable and powerful than it .

This explanation is not clear enough , that Promise What the hell is it  

It's simply a container , It holds an event that will end in the future ( This is usually an asynchronous operation ) Result .

Popular speaking ,Promise Translated as a promise , It's a commitment to the future , Promises may not be fulfilled ( Just like you promised your girlfriend that you would buy her a bag in the future , Just want to deal with it first , It's not certain whether to buy it in the future ), But whether it can be completed or not, Chengdu will have a result .

Promise Use

Promise Is a solution to asynchronous programming , Mainly used to solve the problem of callback hell , It can effectively reduce callback nesting .

grammatically :Promise It's a constructor

functionally :Promise Object is used to encapsulate an asynchronous operation and obtain its success / Failed return value

First, let's think about what are asynchronous operations  

fs File operations     Database operation    ajax Request operation     Timer

The above are asynchronous operations

fs File operations  require('fs').readFile('./xiaojie.txt',(err,data)=>{})
 Database operation    $.get('/server',(data)=>{})
 Timer    setTimeout(() => {}, 2000);

stay promise front , When we do asynchronous operations , It is carried out in the way of pure callback function , Then why do we use promise Well , Can't you use callback function  

Be careful , That's the most important thing , The interview will be asked

  because Promise Support chain calls , It can solve the problem of callback to hell   

Back to hell

So what is hell   Why should we solve him  Promise How to solve it  

Let's solve it one by one :

First, let's look at the following code , We want to output the numbers in three times , One second at a time , Then we must do this :

setTimeout(function () {
    console.log(111);
    setTimeout(function () {
        console.log(222);
        setTimeout(function () {
            console.log(333);
        }, 1000);
    }, 1000);
}, 1000);

Code nesting , In a complex program , It is very difficult to read and to handle exceptions , Because at each layer, we need to exception handle errors , You may write a lot of repetitive code and make the indentation format very redundant , When there are too many nesting layers , There will be “ Back to hell ”. Here's how important it is to write code in a new way . use promise Methods to deal with such problems , It will undoubtedly be more appropriate .

Solution

  promise call chaining   

new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log(111);
        resolve();
    }, 1000);
}).then(() => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(222);
            resolve();
        }, 1000);
    });
}).then(() => {
    setTimeout(() =>{
        console.log(333);
    }, 1000);
});

In this way, the final output effect is the same , And it will change the writing of nested code statements to sequential writing , But do not change the asynchronous process it executes , That's exactly what it is. promise Functions and advantages of the method . 

Promise The basic usage of

ES6 Regulations ,Promise It's a constructor , If it is a constructor, it can instantiate the object .

promise When instantiating an object, you need to accept parameters , This parameter is the value of a function type

The two parameters of this function are resolve and reject .

resolve It means to solve ,reject It means to refuse .

Both are function type data

When the asynchronous task succeeds, call resolve, Called when an asynchronous task fails reject

The following code creates a Promise example .

const p = new Promise((resolve, reject) => {
  // ... some code
    if (/*  Asynchronous operation succeeded  */){
        resolve(value);
    } else {
        reject(error);
    }
});

  resolve() After the call , Can be promise object (p) The status of is set to success   

  reject() contrary , After calling , Can be promise object (p) The status of is set to failed   

We created promise After the instance, you need to call then Method , He needs to receive two parameters when executing , And both parameters are values of function type

p.then((value) => {},(error) => {});

The first parameter is the callback when the object succeeds , The second parameter is the callback when the object fails .

Both parameters are optional , It is not necessary to provide . Accept them all Promise  Object as a parameter .
Popular said , If promise If the object state is successful, the first callback function is executed , If the status fails, execute the second callback function

Promise Initial experience of practice

Let's not start the explanation Promise Various API Sum principle , First do two practical applications , A simple experience Promise.

fs Module read file

This requires us to install node.js Environmental Science ,fs The function of the module is to read and write the hard disk of the computer

Our case requirements are as follows :

Read... In the current directory nba.txt The contents of the document :

  Traditional callback function form : 

// introduce fs modular 
const fs = require('fs');
fs.readFile('./nba.txt', (err, data) => {
    //  If something goes wrong   Throws an error 
    if(err)  throw err;
    // Output the contents of the file without error 
    console.log(data.toString());
});
PS D:\ User directory \Desktop\home\html (2)\4.20> node zyj.js
 Warrior Champion 

In this case, our nba.txt The content in the is output

  Promise Package form : 

// Encapsulate a function  mineReadFile  Read file contents 
// Parameters :  path   File path 
// return :  promise  object 

function mineReadFile(path){
   return new Promise((resolve, reject) => {
       // Read the file 
       require('fs').readFile(path, (err, data) =>{
           // Judge 
           if(err) reject(err);
           // success 
           resolve(data);
       });
   });
}

mineReadFile('./nba.txt')
.then(value=>{
   // Output file content 
   console.log(value.toString());
}, error=>{
   console.log(error);
});

If it works data It's just one. buffer need tostring Method to convert it to a string , If something goes wrong, print out the wrong object

When our output is normal :

PS D:\ User directory \Desktop\home\html (2)\4.20> node zyj.js
 Warrior Champion 

We deliberately typed the wrong path , See what the error will output :

PS D:\ User directory \Desktop\home\html (2)\4.20> node zyj.js
[Error: ENOENT: no such file or directory, open 'D:\ User directory \Desktop\home\html (2)\4.20\na.txt'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'D:\\ User directory \\Desktop\\home\\html (2)\\4.20\\na.txt'
}

The output is error The contents of this error object

Use promise encapsulation ajax Asynchronous requests

<script >
/* Reusable hair  ajax  Requested function : xhr + promise*/
function promiseAjax(url) {
     return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open("GET", url);
            xhr.send();
            xhr.onreadystatechange = () => {
              if (xhr.readyState !== 4) return;
              //  The request is successful ,  call  resolve(value)
              if (xhr.status >= 200 && xhr.status < 300) {
                resolve(xhr.response);
              } else { //  request was aborted ,  call  reject(reason)
                reject(xhr.status);
              }
            }
          })
        }
promiseAjax('http://www.liulongbin.top:3006/api/getbooks').then(data => {
           console.log(' Display success data ', data)
        },
        error => {
           alert(error)
        }) 
</script>

Output results :

When we deliberately mistype the address :

promise Object state properties

Promise The state of the object is not affected by the outside world .Promise Objects have three states :
  pending ( Have in hand )、fulfilled ( Have succeeded ) and rejected ( Failed ).

Once the status changes , It won't change , You can get that at any time .

Promise Yes The state of the elephant changes , There are only two possibilities : from pending Turn into fulfilled(resolved) And from the pending Turn into rejected.

As long as those two things happen , The state is frozen , It won't change , It's going to stay that way .

Only results of asynchronous operations , You can decide which state you are in , No other operation can change this state . This is also Promise The origin of the name , It means the same thing in English “ promise ”, Says nothing else can be changed .

If change has already happened , You again to Promise Object to add a callback function , And you'll get that immediately . With the event (Event) Completely different , The characteristic of the event is , If you missed it , To listen again , You don't get results .

promise Object result value property

This is a promise Another property in the instance object [promiseResult] , Save asynchronous tasks [ success / Failure ] Result

resolve and reject The two methods are to modify the result attribute of the instance object , No one can change except them

Small cases

In the face of Promise After a general understanding , Let's take a look at the following code :

function timeout(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, 'done');
  });
}

timeout(100).then((value) => {
  console.log(value);
});

analysis :

In the above code ,timeout Method returns a Promise Instance object , A result that will not happen for some time . After the appointed time (ms Parameters ) in the future ,  The timer will call resolve(), And put the result value (done) Come in , After the call , Can be promise object (p) The status of is set to success  , When his state changes, it triggers then Method binding callback function , Send in the result value (done) The output from .

Two 、Promise API

Promise Constructors : Promise (excutor) {}

(1) executor function : actuator (resolve, reject) => {}

(2) resolve function : The function we call when the internal definition succeeds value => {}

(3) reject function : The function we call when the internal definition fails reason => {}

a key :executor Will be in Promise Internal immediate synchronization call  

Let's look at the following code

let p = new Promise(function(resolve, reject) {
  console.log('jack');
  resolve();
});

p.then(value=> {
  console.log('andy');
});

console.log('Hi!');

// jack
// Hi!
// andy

In the above code ,Promise Execute as soon as new , So the first output is 'jack'. then ,then Callback function specified by method , It will not be executed until all synchronization tasks of the current script have been executed , So output again 'Hi','andy'  The final output .

actually , The knowledge points related to this operation result are [ Macro task and micro task ]  , Comb separately at the bottom :

  • Macro task : setTimeout , setInterval , Ajax , DOM event
  • Micro task : Promise async/await
  • The execution time of micro task is earlier than that of macro task ( Remember first )

Now let's look at an interview question :

console.log(100);

setTimeout(()=>{
    console.log(200);
})

setTimeout(()=>{
    console.log(201);
})

Promise.resolve().then(()=>{
    console.log(300);
})

console.log(400);

// 100 400 300 200 201

Did everyone do it right , If you don't do it right , Let's combine JS Operation mechanism of You can easily understand :

  • All synchronization tasks are performed on the main thread , Line into an execution stack .
  • In addition to the main thread , There is also a task queue , As long as asynchronous tasks have run results , Just put a time stamp in the task queue .
  • The main thread completes all tasks ( Perform stack clear ), Will read the task queue , First execute the micro task queue, and then execute the macro task queue .
  • Repeat the above three steps .

Promise.prototype.then()

then The method is defined in the prototype object Promise.prototype Upper . What it does is Promise Instance adds a callback function when the state changes

then Method returns a new Promise example  

then Method returns a new one Promise example ( Be careful , Not the original one Promise example ). So we can do the chain notation , namely then The method is called again later then Method .

let p = new Promise((resolve, reject) => { 
  setTimeout(resolve, 1000, 'jack'); 
}); 
p.then(value => {
  console.log(value); 
  return 'andy';
}).then(value => console.log(value));
//jack
//andy

then() Method will return a new Promise object ,  therefore then You can continue to follow one then Method to make a chain call ,  If then The callback function of the method returns data , Then this data will be used as the next then The parameters of the callback function , This knowledge point involves chain call , stay Promise The fifth key question is explained in detail in multiple tasks . Let's have a brief understanding here .

It's a chain then,  Will wait for the former Promise Only when the state changes will it be called

then The callback function of may also return a Promise object , This time will cover then Return by yourself Promise object , The latter callback function , Will wait for this Promise The state of the object changes , Will be called .

let p = new Promise((resolve, reject) => { 
  setTimeout(resolve, 1000, 'jack'); 
}); 
p.then(value => {
  console.log(value); 
  return new Promise((resolve,reject) => {
    setTimeout(resolve,1000,'andy');
  });
}).then(value => console.log(value));
//jack
//andy

In the above code , first then Callback function specified by method , Back to the other Promise object . At this time , the second then Callback function specified by method , Will wait for this new Promise The state of the object changes .

Because the second callback function has a timer , So after a second, the state changes to resolved, the second then The method will not execute until the state changes log Output statement

Promise.prototype.catch()

Promise.prototype.catch() The method is .then(null, rejection) or .then(undefined, rejection) Another name for , Used to specify the callback function when an error occurs .

let p = new Promise((resolve, reject) => { 
  reject('what is the matter');
}); 
p.catch(error => {
  console.log(error);
})
//what is the matter

If Promise Object state changes to rejected, Will call catch() Callback function specified by method , Handle this error .

let p = new Promise((resolve, reject) => { 
  throw new Error(' Error thrown ')
}); 
p.catch(error => {
  console.log(error);
})
//Error:  Error thrown 

In the above code ,Promise Throw an error , Will also be catch() Method to capture .

  It is worth noting that : If Promise The state has become resolved , It's invalid to throw another error . 

let p = new Promise((resolve, reject) => { 
  resolve('success');
  throw new Error(' Error thrown ')
}); 
p.then(value => {
  console.log(value);
}).catch(error => {
  console.log(error);
})
//success

In the above code , Throw an error in resolve After statement , Then you won't be caught , Is equal to not throwing . because Promise Once the state of , Keep that state forever , It won't change .

Promise The error of the object is “ Bubbling ” nature , It's going to go all the way back , Until it is captured . in other words , Mistakes are always next catch Statements capture .

We know everything then Methods will produce a new Promise example , If one Promise The object is followed by multiple then Method , Any one of them throws an error , Will be the last one catch() Capture .

  a key : therefore , Not in then() Method definition Reject Callback function for state ( namely then Second parameter of ), most     Easy to use catch Method , This captures the front then Error in method execution .

Promise.resolve()  

Sometimes you need to convert an existing object to Promise object ,Promise.resolve()  The method plays this role .

let p = Promise.resolve('jack');
console.log(p);

Open console , Look at what the above code outputs :

His result is a Promise object , And the status is success , The successful value is the parameter we passed in 'jack' .

Promise.resolve()  It's equivalent to the following :

Promise.resolve('jack')
//  Equivalent to 
new Promise(resolve => {resolve('jack')})

Promise.resolve()  The parameters of the method are divided into two cases :

The parameter is one Promise example :

If the parameter is Promise example , that Promise.resolve()  No changes will be made 、 Returns the instance intact .

let p1 = Promise.resolve('jack');
let p2 = Promise.resolve(p1);
console.log(p2);
//Promise {[[PromiseState]]: 'fulfilled', [[PromiseResult]]: 'jack'}

The parameter is not Promise Object or does not have any parameters :

Promise.resolve()  Method returns a new one Promise object , Status as resolved

const p = Promise.resolve();

p.then(function () {
  // ...
});

The variables in the code above p  It's just one. Promise object .

It should be noted that , immediately resolve() Of  Promise object , It's in this round “ The event loop ”(event loop) At the end of , Not in the next round “ The event loop ” At the beginning of . 

setTimeout(function () {
  console.log('jack');
}, 0);

Promise.resolve().then(function () {
  console.log('andy');
});

console.log('david');

// david
// andy
// jack

In the above code ,setTimeout( fn , 0) The next round of “ The event loop ” Start with ,Promise.resolve() In the current round “ The event loop ” Execute at the end ,console.log('david') It's immediate execution , So output first .

Promise.reject()   

Promise.reject(reason) Method also returns a new Promise example , The state of the instance is rejected .

let p1 = Promise.reject(' Error ');
console.log(p1);
//Promise { <rejected> ' Error ' }
const p = Promise.reject(' Error ');
//  Equate to 
const p = new Promise((resolve, reject) => reject(' Error '))

p.then(null, function (s) {
  console.log(s)
});
//  Something went wrong 

Even if the parameter we passed in is a successful Promise object , His result was also failure :

let p1 = Promise.reject(new Promise((resolve, reject) => {
    resolve('ok');
}));
console.log(p1);
//Promise { <rejected> Promise { 'ok' } }

Now our Promise object p1 The state of is failure , The result of its failure is the value we passed in , This is the successful Promise object , The simple understanding is , No matter what ,Promise.reject() The returned status must be rejected 

Promise.all()    

Promise.all()  Method is used to add more than one Promise example , Pack into a new one Promise example .

const p = Promise.all([p1, p2, p3]);
  • Promise.all()  Method takes an array as an argument ,
  • p1, p2, p3 All are Promise example , If not , Will call first Promise.resolve Method , Convert parameter to Promise example , Further processing .
let p1 = Promise.resolve('jack');
let p2 = Promise.resolve(111);
const p3 = Promise.all([p1,p2,'andy']);
console.log(p3);

Here we define two states as successful Promise object p1 and p2, We want to pass Promise.all()  Methods will be multiple Promise example , Pack into a new one Promise example p3, But the last element in the parameter array is not Promise Object, but a string , that p3 What's going to be output ?

The output result is shown in the figure above , As we mentioned earlier , If there are elements in the array that are not Promise example , Will call first Promise.resolve Method , Convert parameter to Promise example , Reprocessing .

p The status of the p1, p2, p3 decision , There are two cases :

1. Only  p1, p2, p3 The state of fulfilled ,p The state of fulfilled , here  p1, p2, p3  The return value of consists of an array , Pass to p Callback function for .

2. as long as  p1, p2, p3  One of them is rejected,p The state of rejected , At this time, the first was reject The return value of the instance of , Will pass to p Callback function for .

Let's analyze a piece of code :

const p1 = new Promise((resolve, reject) => {
  resolve('success');
}).then(value => value).catch(reason => reason);

const p2 = new Promise((resolve, reject) => {
  throw new Error(' Wrong report ');
}).then(value => value).catch(reason => reason);

Promise.all([p1, p2]).then(value => {console.log(value)})
.catch(reason => {console.log(reason)});

In the above code ,p1 Meeting resolved,p2 First of all be rejected, however p2 Have their own catch Method , This method returns a new Promise example ,p2 It's actually pointing to this instance . The instance is finished catch After the method , It will become resolved, Lead to Promise.all() Both instances in the method parameters will resolved, So it will call then Callback function specified by method , Instead of calling catch Callback function specified by method .

Here is the output of this code :

If p2 There is no one's own catch Method , Will call Promise.all() Of catch Method , At this time, the output result is like this :

Promise.race()

Promise.race() Again, multiple Promise example , Pack into a new one Promise example .

const p = Promise.race([p1, p2, p3]);

In the above code , as long as p1 , p2 , p3 One of the examples is the first to change the State ,p The state of . The first to change Promise The return value of the instance , It is passed to the p Callback function for . 

Let's analyze what the following code should output :

let p1 = new Promise((resolve,reject)=>{
  setTimeout(() => {
    resolve('ok');
  }, 1000);
})
let p2 = Promise.resolve('success');
let p3 = Promise.resolve('oh year');
const result = Promise.race([p1,p2,p3]);
console.log(result);

Let's take a look first p1,p2,p3 Which of the three of them changed their state first , If p1 Change the state first , that result The result is p1 Decisive , If p1 So successful result Just succeed , The result of its success is result Successful results . But because in our case p1 It's a timer , It's an asynchronous task , That must not be p1, Down the line ,p1 No, that's for sure p2 Change the state first , Let's look at the output from the console :

because p2 The state of success , therefore result The state of is fulfilled, because p2 The result is success, therefore result The result is also result.



3、 ... and 、Promise key problem  

1. How to modify the state of an object

  1. resolve(value): If it is currently pending It will become resolved
  2. reject(reason): If it is currently pending It will become rejected
  3. Throw an exception : If it is currently pending It will become rejected( You can throw one Error Instance object )

2. Whether multiple callbacks can be executed

When promise It is called when it changes to the corresponding state

Let's look at the following code :

let p = new Promise((resolve, reject) => {  resolve('OK');});

p.then(value => { console.log(value); });
p.then(value => { console.log(value+' again')});

We give Promise object p Two callbacks have been developed , Will it execute ? Let's look at the console :

The console prints the output in two callbacks in sequence , If and only if Promise Only when the object changes to the corresponding state will .

If in Promise No internal call resolve, Then his state is pending, So we didn't change the state, so one then Callbacks do not execute

If you change this code to this , Will he have the same result :

let p = new Promise((resolve, reject) => {  resolve('OK');});

p.then(value => {  console.log(value);}).then(value => { console.log(value+' again');});

Let's take a look at the output :

Why the second callback value yes undefined Well ? 

Because on it then The detailed explanation of the method mentioned then Method returns a new one Promise example ( Be careful , Not the original one Promise example )

If then The callback function of the method returns data , Then this data will be used as the next then The parameters of the callback function , But the first one in our example above then Not in it return data , So the second one then I don't know value Who is it? , If we were in the first then Riga return value, In this way, the output result is the same as the original .

3. The sequence of changing state and executing callback

It's possible , Normally, the callback is specified first and then the state is changed , But it is also possible to change the state first and then specify the callback

When Promise The task in the object's executor is the synchronization task , Call directly resolve, This situation is to change first Promise Object state , Then specify the callback

The following example code :

let p = new Promise((resolve,reject) => {
     resolve('success');
});
p.then(value => {console.log(value);});

When will that be then Method first , then resolve What about executing after changing the state ?

When there are asynchronous tasks in the executor function ,  in other words , I need to wait a while to change my state , When you need to enter the corresponding asynchronous task queue for execution , In this case it is then Execute first ,resolve Execute after changing the state

The following example code :

let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        resolve('success');
    }, 1000);
});
p.then(value => {console.log(value);});

Let's summarize :

​ Specify the callback first and then change the State ( asynchronous ):

  1. Specify callback first
  2. Then change the State
  3. After changing the state, it enters the asynchronous queue and executes the callback function

Change the status first, and then specify the callback ( Sync ):

  1. Change state
  2. Specify callback And immediately execute the callback

So how can we change the state first and then specify the callback ?

Be careful : Specifying is not executing

  • Call directly in the actuator resolve()/reject() , Do not use timer and other methods , Direct synchronous operation in the actuator
  • Call after a longer delay then() , stay .then() This method is covered with another layer, such as a delay device

When can we get the data ? 

  • If the callback is specified first , When the state changes , The callback function will call , Get data
  • If you change the state first , When a callback is specified , The callback function will call , Get data

In short , If Promise There are asynchronous tasks in the executor of the object , For example, if the output statement is in the timer , Just specify the callback first , But specifying is not executing . I have to wait Promise When the state of an object changes , Just go back and call the callback function .

4.then What determines the result returned by the method  

We said that before ,then Method returns a new Promise example  , The new one Promise What determines the state of an object , What are the characteristics of its returned results ?

Simple expression : new Promise The state of the object is determined by then() The result of the specified callback function execution determines

Detailed expression :

1. If an exception is thrown , new promise Turn into rejected, reason Exception thrown for

Code example :

let p = new Promise((resolve,reject) => {
    resolve('success');
});
let result = p.then(value => {
     throw ' Error ';
})
console.log(result);

Output results :

2. If yes or no is returned promise Any value of , new promise Turn into resolved, value For the returned value

Code example :

let p = new Promise((resolve,reject) => {
    resolve('success');
});
let result = p.then(value => {
    return 'jack';
})
console.log(result);

Output results :

 

3. If you return another new promise, this promise The result will be new promise Result

Code example :

let p = new Promise((resolve,reject) => {
    resolve('success');
});
let result = p.then(value => {
    return new Promise((resolve,reject) => {
        reject('no');
    })
})
console.log(result);

Output results :

5. Concatenate multiple tasks

1. promise Of then() Back to a new promise, Can be seen as then() Chain call of

2. adopt then Linked calls to connect multiple synchronizations / Asynchronous task , So that we can use then() Concatenate multiple synchronous or asynchronous operations into a synchronous queue

  Let's take a look at the code below :

let p = new Promise((resolve,reject) => {
     setTimeout(() => {
          resolve('ok');
     },1000)
});
p.then(value => {
     return new Promise((resolve,reject) => {
          resolve('success');
     })
}).then(value => {
     console.log(value);
})

Output results :

Because the first one then It's a new Promise object , So this  promise The result will be new promise Result , So it will output success.

Next, let's add another... To the above code then Callback :

let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        resolve('ok');
    },1000)
});
p.then(value => {
    return new Promise((resolve,reject) => {
        resolve('success');
    })
}).then(value => {
    console.log(value);
}).then(value => {
    console.log(value);
})

This last value What will the output be ? The answer is  undefined

We know then The return result of is Promise object , It's this Promise The state of an object is determined by the return value of the callback function it specifies , the second then The return value of the callback function of is null , Namely undefined,undefined Obviously not Promise Object of type , We talked about that before , If yes or no is returned promise Any value of , new promise Turn into resolved, That is, the state is successful , The result of his success is the result of his return undefined. Because the second one then Back to Promise The object succeeded , Will execute the last then The first callback of , And output the results of his success , That is to say undefined. This is it. then Chain call of

6. extraordinary transmission

  • When using promise Of then Chain call , Failed callbacks can be specified at the end
  • Exception in any previous operation , Will be sent to the last failed callback for processing

Sample code :

let p = new Promise((resolve,reject) => {
     setTimeout(() => {
          reject(' Error ');
     },1000)
});
p.then(value => {
     console.log(000);
}).then(value => {
     console.log(111);
}).then(value => {
     console.log(222);
}).catch(error => {
     console.warn(error);
})

Let's take a look at the output first :

His output is just the first Promise The value of the result of his failure , We don't need to take care of the middle link , There is no need to specify a failed callback , You only need to specify a failed callback at the end to process the failed result . This phenomenon belongs to abnormal penetration .

For example, we throw an error in the middle link , Look at the last catch Can you capture  :

let p = new Promise((resolve,reject) => {
     setTimeout(() => {
          resolve('ok');
     },1000)
});
p.then(value => {
     throw ' Error ';
}).then(value => {
     console.log(111);
}).then(value => {
     console.log(222);
}).catch(error => {
     console.warn(error);
})

Output results :

first then The error thrown in the callback is determined by the last catch Method to handle , This is abnormal penetration .

7. How to terminate Promise chain  

When promise When the state changes , His chain calls will take effect , Well, if we have a practical need : We have 4 individual then(), But there are conditional judgments , For example, when I meet or do not meet the requirements of article 2 individual then When the conditions , To break the chain call directly , Don't go down then, How to ?

  Method : In this callback function, a pending State of Promise object  

Sample code :

let p = new Promise((resolve,reject) => {
     setTimeout(() => {
          resolve('ok');
     },1000)
});
p.then(value => {
     console.log(111);
}).then(value => {
     console.log(222);
     return new Promise(()=>{})
}).then(value => {
     console.log(333);
}).then(value => {
     console.log(444);
})

Output results :

Sample analysis :

interrupt Promise There is and only one way to chain , That is, you must return a pending State of Promise object . Because if you return a successful Promise object , Even if the returned result is undefined however then The callback in will still execute , Only pending State of Promise Different objects , Because if the callback returns a pending, So this then The returned status is also pending Of Promise object , If the first one ( In this question )then The return is pending State of Promise object , Then the following then Method cannot be executed , Because the state hasn't changed , You can't execute without changing the State .

  In short : Change the current state to pending, So the back then and catch No execution   

  Here we are Promise The first part of is finished , We learned Promise dependent API And some key issues , But these are far from enough for us to go to a big factory for an interview .Promise In the second part, we will try to customize the encapsulation Promise. Let's first learn how to use it , Then start with the principle and learn how to realize it .

I hope the students here can support Xiaojie with one key and three links !

版权声明
本文为[Xiaojie learning front end]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231811052703.html