A Promise from scratch

A Promise from zero)

4. Key Promise questions

1. How to change the state of promise?

(1) Resolve (value) : Resolved if it is pending

(2) Reject (reason) : If it is pending, it changes to Rejected

(3) Raise exception: If the value is pending, it changes to Rejected

const p = new Promise((resolve, Reject) => {//resolve(1) // Pending => discharge (resolved) // Reject (2) // Pending => Discharge (rejected) Promise changes to the discharge (rejected) state Throw new Error(' rejected ') // Throw new Error(' rejected ') P.chen (value => {}, reason => {console.log('reason',reason)}) // Reason error: errorCopy the code

2. Will multiple success/failure callbacks specified by a promise be called?

This is called whenever a promise changes to the corresponding state

const p = new Promise((resolve, reject) => {
  //resolve(1)
  reject(2)
})
p.then(
  value => {},
  reason => {console.log('reason',reason)}
)
p.then(
  value => {},
  reason => {console.log('reason2',reason)}
)
// reason 2
// reason2 2
Copy the code

3. Which comes first, changing the promise state or specifying the callback function?

Either is possible. The general rule is to specify a callback and then change the state, but you can change the state and then specify a callback

The first callback is successful and the second callback is failed, but the callback is not executed. The promise object is synchronous, execute resolve or reject and proceed with the THEN and callback, or asynchronous, execute THEN and the callback will be executed after the async execution

  • How do I change state and then specify a callback?

    1. Synchronize tasks in the executor directly by calling resolve()/reject()
    2. Delay calling then() longer
let p = new Promise((resolve, reject) => { // setTimeout(() => { resolve('OK'); / /}, 1000); // if asynchrony exists, specify the callback; otherwise, change the state. p.then(value => { console.log(value); },reason=>{ })Copy the code
  • When will we get the data?
    1. If the callback is specified first, the callback function will be called to retrieve the data when the state changes
    2. If the state is changed first, the callback function is called to retrieve the data when the callback is specified
New Promise((resolve, reject) => {setTimeout(() => {resolve(1) // change state}, 1000)}). reason =>{} )Copy the code

In this case, specify a callback function and save the currently specified callback function. Then change the state (specifying the data), and execute the previously saved callback asynchronously.

New Promise((resolve, reject) =>{resolve(1) // change state}). Then (// specify the callback function value =>{}, reason =>{})Copy the code

In this way, the state is changed (and the data is specified), and the callback function is specified (no further saving is required), and the callback function is executed asynchronously

4. What determines the result state of the new promise returned by promise.then()?

(1) Simple expression: the result of the execution of the callback function specified by then()

let p = new Promise((resolve, reject) => { resolve('ok'); }); Let result = p.teng (value => {console.log(value); }, reason => { console.warn(reason); }); console.log(result);Copy the code

(2) Detailed expression:

(1) If an exception is raised, the new promise changes to Rejected. Reason is the exception raised

let p = new Promise((resolve, reject) => { resolve('ok'); }); Let result = p.chen (value => {//1. Throw error throw 'problem '; }, reason => { console.warn(reason); }); console.log(result);Copy the code

② If any non-PROMISE value is returned, the new promise becomes resolved and value is the returned value

let p = new Promise((resolve, reject) => { resolve('ok'); }); Let result = p.teng (value => {//2. Return a non-Promise object. Return 521; }, reason => { console.warn(reason); }); console.log(result);Copy the code

③ If another new promise is returned, the result of that promise becomes the result of the new promise

let p = new Promise((resolve, reject) => { resolve('ok'); }); Let result = p.chen (value => {//3. Return new Promise((resolve, reject) => {// resolve('success'); reject('error'); }); }, reason => { console.warn(reason); }); console.log(result);Copy the code

5. How does promise string together multiple action tasks?

(1) Promise’s then() returns a new promise, which can be combined into a chain call of then()

(2) Concatenate multiple synchronous/asynchronous tasks through chain calls to THEN

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); // success
}).then(value => {
  console.log(value); // undefined
})
Copy the code

exercises

new Promise((resolve, reject) => {
  resolve(1)
}).then(
  value => {
    console.log('onResolved1()', value)
  },
  reason => {
    console.log('onRejected1()', reason)
  }
).then(
  value => {
    console.log('onResolved2()', value)
  },
  reason => {
    console.log('onRejected2()', reason)
  }
)
// onResolved1() 1
// onResolved2() undefined
Copy the code

new Promise((resolve, reject) => { resolve(1) }).then( value => { console.log('onResolved1()', value) //return 2 // onResolved2() 2 //return Promise.resolve(3) // onResolved2() 3 //return Promise.reject(4) // onRejected2() 4 //throw 5 // onRejected2() 5 }, reason => { console.log('onRejected1()', reason) } ).then( value => { console.log('onResolved2()', value) }, reason => { console.log('onRejected2()', OnResolved1 () 1 // onResolved2() undefined // Promise {< depressing >: undefined} //Copy the code

New Promise((resolve, reject) => {setTimeout(() => {console.log(' execute task 1(async)') resolve(1)}, 1000)}). Then (value => {console.log(' result of task 1 ', Log (' Perform task 2(synchronize)') return 2 // Synchronize task directly return result}). Then (value => {console.log(' synchronize task 2 ', value) return new Promise((resolve, Reject) => {// Async tasks need to be wrapped in a Promise object setTimeout(() => {console.log(' perform task 3(async)') resolve(3)}, 1000)})}). Then (value => {console.log(' result of task 3 ', Value)}) // Perform task 1(asynchronous) // Result 1 of Task 1 // Perform task 2(synchronous) // Result 2 of Task 2 // Perform task 3(asynchronous) // Result 3 of task 3Copy the code

6.Promise abnormal penetration?

(1) When using promise’s then chain call, you can specify the failed callback at the end

(2) Any previous operation is abnormal, will be passed to the last failed callback processing

<script> let p = new Promise((resolve, reject) => { setTimeout(() => { resolve('OK'); // reject('Err'); }, 1000); }); p.then(value => { // console.log(111); Throw 'failed! '; }).then(value => { console.log(222); }).then(value => { console.log(333); }).catch(reason => { console.warn(reason); }); </script>Copy the code

sample

new Promise((resolve, reject) => {
   //resolve(1)
   reject(1)
}).then(
  value => {
    console.log('onResolved1()', value)
    return 2
  }
).then(
  value => {
    console.log('onResolved2()', value)
    return 3
  }
).then(
  value => {
    console.log('onResolved3()', value)
  }
).catch(
  reason => {
    console.log('onRejected1()', reason)
  }
)
// onRejected1() 1
Copy the code

Throw reason => {throw reason}

new Promise((resolve, reject) => { //resolve(1) reject(1) }).then( value => { console.log('onResolved1()', Then (value => {console.log('onResolved2()', value => {console.log('onResolved2()'), Then (value => {console.log('onResolved3()', value)}, value => {console.log('onResolved3()', value)}, Reason => {console.log('onRejected1()', reason) } ) // onRejected1() 1Copy the code

So the result of a failure is processed layer by layer and passed to the catch.

Alternatively, replace reason => {throw reason} with reason => promise.reject (reason)

7. Break the Promise chain?

When using a promise’s then chain call, it breaks in the middle, and no subsequent callback function is called

Solution: Return a Promise object in a pending state in the callback function

<script> let p = new Promise((resolve, reject) => { setTimeout(() => { resolve('OK'); }, 1000); }); p.then(value => { console.log(111); Return new Promise(() => {}); }).then(value => { console.log(222); }).then(value => { console.log(333); }).catch(reason => { console.warn(reason); }); </script>Copy the code

sample

new Promise((resolve, reject) => {
   //resolve(1)
   reject(1)
}).then(
  value => {
    console.log('onResolved1()', value)
    return 2
  }
).then(
  value => {
    console.log('onResolved2()', value)
    return 3
  }
).then(
  value => {
    console.log('onResolved3()', value)
  }
).catch(
  reason => {
    console.log('onRejected1()', reason)
  }
).then(
  value => {
    console.log('onResolved4()', value)
  },
  reason => {
    console.log('onRejected2()', reason)
  }
)
// onRejected1() 1
// onResolved4() undefined
Copy the code

To interrupt execution in a catch, write:

new Promise((resolve, reject) => { //resolve(1) reject(1) }).then( value => { console.log('onResolved1()', value) return 2 } ).then( value => { console.log('onResolved2()', value) return 3 } ).then( value => { console.log('onResolved3()', value) } ).catch( reason => { console.log('onRejected1()', Reason) return new Promise(() => {}) // Return a pending Promise}). Then (value => {console.log('onResolved4()', value)}, reason => { console.log('onRejected2()', reason) } ) // onRejected1() 1Copy the code

Return a new Promise in a catch with the promise state unchanged.

Since the new promise result returned determines the result in the subsequent THEN, there is no result in the subsequent THEN either.

This achieves the effect of breaking the promise chain.

5. async with await

5.1 async

  1. The return value of the function is a Promise object
  2. The result of the Promise object is determined by the return value executed by the async function
The new promise will change to Resolved if an exception is returned, and the new promise will change to Rejected and reason will change to Resolved if an exception is returned. Async function main(){//1. If a new promise is returned, the result of this promise will be the result of the new promise. If the return value is a non-Promise type // return 521; Return new Promise((resolve, reject) => {// // resolve('OK'); // reject('Error'); / /}); //3. Throw "Oh NO"; } let result = main(); console.log(result); </script>Copy the code

1. Return a non-promise object, and return a new Promise as resolve.

 async function main(){
             return '123';
          }
          let res = main();
          console.log(res);
Copy the code

2. If the return is a Promise object, it depends on the return result:

Such as:

 async function main(){
             return new Promise((resolve,reject) = >{
                 reject('NO');
             });
          }
          let res = main();
          console.log(res);

Copy the code

3. Throwing an exception also fails:

 async function main(){
             return new Promise((resolve,reject) = >{
                 reject('NO');
             });
          }
          let res = main();
          console.log(res);
Copy the code

5.2 await

  1. The expression to the right of await is usually a promise object, but it can be any other value
  2. If the expression is a Promise object, await returns the promise success value
  3. If the expression is another value, return this value directly as await

Note:

  1. Await must be written in async functions, but async functions can have no await
  2. If the await promise fails, an exception is thrown, requiring a try… Catch processing
<script> async function main() { let p1 = new Promise((resolve, reject) => { resolve('OK'); }) let p2 = new Promise((resolve, reject) => { reject('Error'); }) // let res = await p1; console.log(res); //2. Let res2 = await 20; console.log(res2); //3. If promise is in a failed state try {let res3 = await p2; } catch (e) { console.log(e); } } main(); </script>Copy the code

Async combined with await.js instances

/** * resource 1.html 2.html 3.html file content */ const fs = require('fs'); const util = require('util'); const mineReadFile = util.promisify(fs.readFile); // fs.readfile ('./resource/1.html', (err, data1) => {// if(err) throw err; // fs.readFile('./resource/2.html', (err, data2) => { // if(err) throw err; // fs.readFile('./resource/3.html', (err, data3) => { // if(err) throw err; // console.log(data1 + data2 + data3); / /}); / /}); / /}); Async function main(){try{let data1 = await mineReadFile('./resource/1x.html'); let data2 = await mineReadFile('./resource/2.html'); let data3 = await mineReadFile('./resource/3.html'); console.log(data1 + data2 + data3); }catch(e){ console.log(e.code); } } main();Copy the code

Async combined with await.html instance

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, </title> </head> <body> <button ID =" BTN "</button> <script> // Encapsulates an AJAX callback, Function sendAJAX(url){return new promise ((resolve, reject) => {const XHR = new XMLHttpRequest(); xhr.responseType = 'json'; xhr.open("GET", url); xhr.send(); Xhr.onreadystatechange = function(){if(xhr.readyState === 4){if(xhr.status >= 200 && xhr.status < 300){ Resolve (xhr.response); }else{ reject(xhr.status); }}}}); } / / jokes interface address https://api.apiopen.top/getJoke let BTN = document. QuerySelector (' # BTN); BTN. AddEventListener (' click ', async function () {/ / jokes information let duanzi = await sendAJAX (' https://api.apiopen.top/getJoke '); console.log(duanzi); }); </script> </body> </html>Copy the code

5.3 Comprehensive Exercises

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, > <title>Document</title> </head> <body> <script> function fn1() {return promise.resolve (1)} Function fn2() {return 2} function fn3() {return promise.reject (3) {return promise.test ()} function fn4() {return promise.reject (3) {return promise.test ()} function fn4() Async function fn5() {return 4} async function fn() {// Async function fn() {// // const result = await fn1() // console.log('result: ', result) // return result + 10 // await is a non-promise data const result = await fn2() console.log('result: ', // const result = await fn3() //} catch (e) {// console.log(e); // const result = await fn4() //} catch (e) {// console.log(e); // } } // fn() async function test() { try { const result2 = await fn() console.log('result2', result2) } catch (error) { console.log('error', error) } try { const result3 = await fn4() console.log('result4', result3) } catch (error) { console.log('error', error) } } test() </script> </body> </html>Copy the code

Fn () not running, running test ()

reference

Callback function -Promise

ECMAScript 6 Getting started with Promise objects