当前位置:网站首页>12 examples to consolidate promise Foundation

12 examples to consolidate promise Foundation

2022-04-23 18:48:00 xingba-coder

Often used in work promise,async + await, When you encounter some problems, you need to use basic knowledge, and there will always be some who don't remember , Just review the authoritative guidelines and es6 Introduction to the standard , It took me a few days to write this article . Like students, please use your hand to make a fortune and point out a praise , Please point out the mistakes in the article .

Patients with a

new Promise((resolve,reject) =>{
  console.log('11')
  resolve()
  console.log('Promise')
})
console.log('start')

result :

11
Promise
start

analysis :

  1. Promise Execute as soon as new , From top to bottom , Print 11
  2. And then meet resolve(),Promise State by pending Turn into fulfilled
  3. But the call resolve or reject It doesn't end Promise The implementation of the parameter function of , So it goes down , Print out Promise
  4. Keep going , Print out start
    summary : call resolve or reject It doesn't end Promise The implementation of the parameter function of

Look at another example with similar code, but the execution process is different

Example 2

new Promise((resolve, reject) => {
  return resolve(1);
  console.log(2);
}).then((res) =>{
  console.log('then',res)
})

result :

then 1

analysis :

  1. Promise Execute as soon as new , meet resolve(1),Promise State by pending Turn into fulfilled
  2. But here we add return,console.log(2) Not execute
  3. perform .then(), Print out then 1
    result :Promise Add... To the parameter function return, The following statements will not be executed ,2 Will not be printed ..then() and .catch() It's the same in China .

Guess what the following execution will be

new Promise((resolve, reject) => {
  resolve(1);
}).then((res) =>{
  return 2;
  console.log('then1',res)
}).then((res) =>{
  console.log('then2',res)
  throw new Error('error')
}).catch((err) =>{
  return 'catch Return value '
  console.log('catch',err)
}).then((res) =>{
  console.log('then3',res)
})

result :

then2 2
then3 catch Return value 

analysis :

  1. new Promise Execute now ,resolve(1) take 1 Pass as a return value to .then()
  2. perform .then(), encounter return 2, amount to return Promise.resolve(2), Because of the addition of return, hinder then1 Will not be printed
  3. Execute the second .then(), Print then2 2, Then throw an error , It's equivalent to executing return Promise.reject('error')
  4. To perform the ,.catch() Error caught , and return 'catch Return value ', amount to return Promise.resolve('catch Return value '), Similarly, the following cosnole.log('catch',err) Not execute
  5. final .then() Will receive the above return value , And print then3 catch Return value

Example 3

Promise.resolve('start')
.then((res) =>{
  console.log('then1',res)
  return 11  // amount to  return Promise.resolve(11)
}).then((res) =>{
  console.log('then2',res)  // amount to  return Promise.resolve(undefined)
}).then((res) =>{
  console.log('then3',res)
  throw new Error('then3 error') // amount to  return Promise.reject(new Error('then3 error'))
}).catch((res) =>{
  console.log('catch',res)
})

result :

then1 start
then2 11
then3 undefined
catch Error: then3 error

analysis : stay Promise in , Returns any non promise The value of will be wrapped into promise object

Example 4

const promise = new Promise((resolve, reject) => {
  console.log(1);
  console.log(2);
});
promise.then(() => {
  console.log(3);
});
console.log(4);

result :

1 2 4

analysis :

  1. new Promise Execute now , Print 1 and 2,
  2. encounter promise.then(), because Promise There is no resolve() perhaps reject(), therefore promise It will always be pending,promise.then() Method will not execute ,3 Will not be printed ,
  3. Keep going , Print 4
    summary :promise There's no resolve() or reject(),promise It will always be pending state , And the corresponding... Will not be executed .then() perhaps .catch()

Example 5 :.then() Parameters of

new Promise((resolve,reject) =>{
    resolve('start')
})
.then(1)
.then(Promise.resolve(2))
.then((res) =>{
    console.log(res)
})

result :

start

analysis :

  1. Promise Of .then  perhaps  .catch  The expected parameter of is a function , If a non function is passed in, value traversal will occur , therefore .then(1) amount to .then((res) => Promise.resolve(res)),
  2. .then(Promise.resolve(2)) amount to
.then((res) => {
    Promise.resolve(2)
    return Promise.resolve(res)
})
  1. final .then() Print start

summary :.then  perhaps  .catch  The expected parameter of is a function , If a non function is passed in, value traversal will occur

Add another line to the above example .then(console.log), The print results are different again

new Promise((resolve,reject) =>{
    resolve('start')
})
.then(1)
.then(Promise.resolve(2))
.then(console.log)
.then((res) =>{
    console.log('res',res)
})

result :

start
res undefined

analysis :

  1. start By the third .then() Printed ,
  2. .then(console.log) amount to
.then((res) =>{
    console.log(res)
    return Promise.resolve(undefined)
})

Example 6 :Promise The state of

const p = new Promise((resolve,reject) =>{
  resolve('11')
})
p.then(() =>{
  console.log('then1',p)
})
p.then(() =>{
  console.log('then2',p)
})

result :

then1 Promise {<fulfilled>: '11'}
then2 Promise {<fulfilled>: '11'}

analysis :Promise Once you change your state, you can't change it anymore

Example 7 :.catch() Handling errors

new Promise((resolve,reject) =>{
    resolve()
}).then((res) =>{
    throw new Error('throw error')
},(err) =>{
    console.log('err',err)
}).catch((err) =>{
    console.log('catch:',err)
})

result :

catch: Error: throw error

analysis : Yes promise for , Handling errors can give .then() Method passes the second function , But the problem is .then() The second function in cannot catch the error of the first function . While using .catch() Then you can catch the error thrown by the upper layer

Example 8 :.catch() Callback

new Promise((resolve,reject) =>{
    reject()
}).catch((err) =>{
    return 'catch1  Back to normal '
}).then((res) =>{
    console.log('then1:',res)
}).catch((err) =>{
    console.log('catch2:',err)
})

result :

then1: catch1  Back to normal 

analysis :

  1. new Promise in reject(),promise State by pending To rejected
  2. perform .catch(), and return 'catch1 Back to normal ', This is the same thing as Promise.resolve('catch1 Back to normal ')
  3. perform .then(), Print then1
    summary :.catch() The callback returns normally , The return value will be passed to the associated promise

And in the .catch() Throw error in , Will be next .catch() Capture , If not redefined .catch() Then the error will be thrown directly

new Promise((resolve,reject) =>{
    reject()
}).catch((err) =>{
    throw new Error('ee')
}).then((res) =>{
    console.log('then1:',res)
}).catch((err) =>{
    console.log('catch2:',err)
})

result :

catch2: Error: ee

Example 9

Promise.reject('start')
.catch((res) =>{
  console.log('catch1',res)
  return new Error('new error1')
}).then((res) =>{
  console.log('then1',res)
  return new Error('new error2')
}).then((res) =>{
  console.log('then2',res)
}).catch((err) =>{
  console.log('catch2',err)
})

result :

catch1 start
then1 Error: new error1
then2 Error: new error2

analysis :

  1. From top to bottom start Will be .catch() Capture , And print catch1 start
  2. Carry on ,.catch() Return to one promise Wrapped wrong object error1, Note that this is the wrong object , Will be handled by the current object , Not a mistake ; amount to Promise.resolve(new Error('error1')); therefore .catch() The return value will be followed by .then() Method received , And print then1 Error: new error1
  3. Carry on ,.then() Back to another promise Wrapped wrong object error2, Again, it won't be treated as a mistake by the last .catch() Capture , But will be next .then() Received , At this point then2 Error: new error2

summary :.then perhaps .catch in return One error Object does not throw an error , So it won't be followed by .catch Capture

Example 10

const p = new Promise((resolve,reject) =>{
  resolve(11)
}).then(() =>{
  return p
})

result :

Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise>

analysis :.then() or .catch() If the returned value is promise In itself , It's going to create a dead cycle ; Like a wireless callback , Keep registering 、 call .then()

Example 11

Promise.resolve('start')
.finally((res1) =>{
  console.log('finally',res1)
  return 'finally'
}).then((res2) =>{
  console.log('then',res2)
}).finally(() =>{
  throw new Error('error')
}).catch((res3) =>{
  console.log('catch',res3)
})

result :

finally undefined
then start
catch Error: error

analysis :

  1. finally The callback function of cannot receive promise Result , therefore res1 The return is undefined
  2. finally If the return value of does not throw an error, it defaults to the previous promise The return value of , therefore .then() Method actually receives Promise.resolve('start') The return value of , Print is start
  3. then .then() There is no way return Any value , This will be equivalent to Promise.resolve('undefined')
  4. Go down and run into finally, here .finally() Method threw an error , Will be the next nearest .catch() Methods to capture , therefore res3 Print the Error:error

Example 12 : Serial promise

Pass in a url Array of components , Execute the... In the array in order url And return the result , The following example fetchUrl Function can be set for testing setTimeout, In the actual development, it is similar to this :

function fetchUrl(url){
  return fetch(url)
    .then((response) =>{
      return response.text()
    }).then((val) =>{
      arr.push(val)
    })
}

promise Realization

var urls = [1,2,3,4]
function fetchAll(urls){
  let arr = []
  let p = Promise.resolve(undefined)
  function fetchUrl(url){
    return new Promise((resolve,reject) =>{
      setTimeout(() =>{
        console.log(url)
        resolve(url*2)
      },1000)
    })
  }
  for (let url of urls) {
    p = p.then((function(url){
      return () => fetchUrl(url)
    })(url)).then((res) =>{
      arr.push(res)
    })
  }
  return p.then(() => arr)
}
fetchAll(urls).then((res) =>{
  console.log(res)
})

analysis :

  1. fetchAll It is defined fetchUrl function , This function will call url Corresponding interface , The return value will be used promise packing , And save the return value in arr in
  2. What needs to be noted here is , If you write in a loop p = p.then(() => fetchUrl(url)), So this url Will be the last in the array url
  3. Because p.then() The parameter callback in is an asynchronous task , During the loop, the parameter callback will be put into Micro task queue , Not immediately , This leads to the failure to bind the correct url
  4. So in for of In circulation p.then() The parameter callback of needs to bind each with an immediate execution expression url( Or use forEach loop ,forEach The inside of the loop will execute a callback function for each element )
    result :
1
2
3
4
[2, 4, 6, 8]

async await Realization

var urls = [1,2,3,4]
function fetchUrl(url){
  return new Promise((resolve,reject) =>{
    setTimeout(() =>{
      console.log(url)
      resolve(url*2)
    },1000)
  })
}
async function awaitFetch(urls) {
  let arr = []
  for (let url of urls){
      let p = await fetchUrl(url)
      arr.push(p)
  }
  console.log(arr)
  return arr
}
awaitFetch(urls)

analysis :await I'll wait for you later fetch(url) Back to promise resolve() after , To execute the following code , Before that ,await Code execution after blocking , So this for of A loop is equivalent to a synchronous loop
result :

1
2
3
4
[2, 4, 6, 8]

Generator implementation

var urls = [1,2,3,4]
function fetchUrl(url){
  return new Promise((resolve,reject) =>{
    setTimeout(() =>{
      console.log(url)
      resolve(url*2)
    },1000)
  })
}
async function* fetchGen(urls){
  for (let url of urls){
      let p = await fetchUrl(url)
      yield p
  }
}
async function fetchAllByGen(urls) {
  let arr = []
  for await(let p of fetchGen(urls)){
      arr.push(p)
  }
  console.log(arr)
  return arr;
}
fetchAllByGen(urls)

analysis :

  1. for of Loops are used exclusively for iteratable objects , The generator is an iterator object .fetchGen Is an asynchronous generator function
  2. stay for await In circulation , Each cycle will wait fetchGen(url) Return results , I'm going to keep going arr.push(p) The operation of
  3. In order to test , take fetchUrl Function fetch api Changed to setTimeout

result :

1
2
3
4
[2, 4, 6, 8]

版权声明
本文为[xingba-coder]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231847089411.html