Promise detailed explanation and key issues

Promise object

Pre-knowledge

function objects and instance objects

  1. How to distinguish function from object formula: the left side of the parentheses is the function, and the left side of the dot is the object
  2. The left side of the point is the object, where the object is divided into: function object, instance object
    // 函数对象 Person
    function Person () {
          
          }
    
    // 实例对象 person
    const person = new Person()
    

Two callback functions

  1. Callback functions are divided into two types: synchronous callback functions and asynchronous callback functions

  2. Synchronous callback function:

    • execute immediately
    • will not be queued
    • Such as: the callback function in the forEach function
      const arr = [1, 2, 3]
      arr.forEach(item => {
              
               // 同步回调:立即执行
        console.log(item)
      })
      console.log('forEach执行完毕后执行输出')
      
  3. asynchronous callback function

    • not executed immediately

    • put in the queue first

    • Such as: timer, ajax request

      setTimeout(() => {
              
              
        console.log('setTimeout') // 异步回调:先放入队列,等待执行
      }, 0)
      console.log('在定时间结束之前执行')
      

Common built-in errors

  1. ReferenceError: reference error

    console.log(a) // ReferenceError: a is not defined
    
  2. TypeError: type error

    const a = null
    console.log(a.xxx) // TypeError: Cannot read property 'xxx' for undefined
    
  3. RangeError: range error (data value is not within its allowed range)

    function fun () {
          
          
    	fun()
    }
    fun() // RangeError: Maximum call stack size exceeded
    
  4. SyntaxError: syntax error

    const text = """" // SyntaxError:Unexpected string
    

Error handling - catch and throw

  1. Catching errors: try...catch

  2. Throw an error: throw

    // 抛出异常
    function fun () {
          
          
      if (new Date.now()%2 == 1) {
          
          
        console.log('ok')
      } else {
          
          
        // 抛出异常
        throw new Error('not')
      }
    }
    
    // 捕获抛出的异常
    try {
          
          
      fun ()
    } catch (err) {
          
          
      alert(err.message) // 弹出框信息为not
    }
    

Promise

What is Promise

  1. A very important and useful feature in ES6: Promise
  2. Promise is a new solution for asynchronous programming in JS
    • The old asynchronous programming solution is: pure callback form, which is easy to cause callback hell problem
  3. Concrete expression:
    1. Syntactically: Promise is a constructor
    2. Functionally speaking: the promise object is used to encapsulate an asynchronous operation and obtain its result
    3. Promise is a solution for asynchronous programming, which expresses asynchronous operations in the process of synchronous operations, avoiding layers of nested callback functions
    4. It was created to solve the asynchronous processing callback hell (that is, the problem of loop nesting)
    5. The role of promise: When there are asynchronous operations, especially when asynchronous operations nest multiple layers of asynchronous operations and callback hell occurs, these asynchronous operations are handled in an elegant way to increase the readability and maintainability of the code

The three states of Promise

  1. When there is an asynchronous operation in development, you can wrap a Promise for the asynchronous operation

  2. There will be three states after the asynchronous operation

    1. pending : Waiting status (neither cashed nor rejected), such as a network request in progress, or the timer has not expired
    2. resolved : Satisfied state (the operation is successfully completed), when we actively call back resolve, we are in this state, and will call back then()
    3. rejected : rejected state (operation failed), when we actively call back reject, we are in this state, and call back catch()
  3. When a promise is called, it starts out in a pending state . This means that the calling function continues executing while the promise is still pending until resolved, providing the calling function with whatever data was requested

  4. The created promise will eventually end in a resolved state (resolved) or a rejected state (rejected), and call the corresponding callback function (passed to then and catch ) when completed

  5. flow chart

    image-20221114102524688

Promise chain call

  1. Either then or catch can return a Promise object

  2. Therefore, our code can actually be chained

  3. You can directly wrap the new data through Promise and return the Promise object

    1. Promise.resolve() : wrap the data into a Promise object, and internally call back the resolve() function (the callback function after success)
    2. Promise.reject() : wrap the data into a Promise object, and internally call back the reject() function (the callback function after failure)
  4. Since the instance created by Promise is an asynchronous operation, the result of this asynchronous operation can only have two states

    1. State 1 : The asynchronous execution needs to be called internally if the asynchronous execution is successful, and the successful callback function resolve returns the result to the caller
    2. State 2 : If the asynchronous execution fails, it needs to be called internally, and the successful callback function reject returns the result to the caller
    3. Since the instance of Promise is an asynchronous operation, after getting the operation result, return cannot be used to return the operation result to the caller. At this time, only the form of callback function can be used to return the result of success or failure to the caller

Promise API

  1. Promise constructor :Promise (excutor) {}

    • Excutor(): Synchronous execution, the content in the function body
  2. Promise.prototype.then(onResolved, onRejected) => {}

    • onResolved(): callback function on success
    • onRejected(): Callback function on failure
    • Description: What is returned is a new Promise object
    const p = new Promise()
    p.then(
      // onResolved()
      res => {
          
          }, 
      // onRejected()
      err => {
          
          }
    )
    
  3. Promise.prototype.catch()(onRejected) => {}

    • onRejected(): Callback function on failure
    • Description: syntactic sugar of then(), equivalent to(undefined, onRejected) => {}
  4. Promise.resolve(value)

    • value: success data or (success/failure) promise object
  5. Promise.reject(value)

    • value: failed data reason or (failed) promise object
  6. Promise.all(promises)

    • promises: an array containing multiple promises, such as: [promise1, promise2, promise3]
    • Description: Return a new promise, only if all the promises in the array succeed, will it return success
  7. Promise.race(promises)

    • promises: an array containing multiple promises, such as: [promise1, promise2, promise3]
    • Description: Return a new promise, which is the first fulfilled promise in the array

Key Issues in Promises

  1. ​ How to change the state of promise?

    • resolve(): pending state -> resolved state
    • reject():pending status -> rejected status
    • Throwing an exception throw new Error()/ throw xxx: pending status -> rejected status
  2. A promise specifies multiple success/failure callback functions, will they all be called?

    • When the promise changes to the corresponding state, the callback function that specifies the corresponding state will be called
  3. Which one comes first to change the promise state and specify the order of the callback function?

    • It is possible; under normal circumstances, the callback function is specified first, and then the state is changed

      // 先指定回调函数,后改变状态
      new Promise((resolve, reject) => {
              
              
        setTimeOut(() => {
              
              
          resolve() // 用定时器模块异步请求,改变状态
        }, 1000)
      }).then( // then是同步进行调用的
      	res => {
              
               .... }, // 同步执行,先指定成功的回调函数
        err => {
              
               .... } // 同步执行,先指定失败的回调函数
      )
      
      // 先改变状态,后指定回调函数
      new Promise((resolve, reject) => {
              
              
        resolve() // 同步执行,先改变promise的状态
      }).then(
      	res => {
              
               .... }, // 同步执行,后指定成功的回调函数
        err => {
              
               .... } // 同步执行,后指定失败的回调函数
      )
      
  4. Key points : When promises are chained, what determines the result status of the new promise generated by the callback function executed by promise.then()?

    • Determined by the execution result of the callback function specified by the current then

      // 情况一
      new Promise((resolve, reject) => {
              
              
        setTimeOut(() => {
              
              
          resolve(111) // 情况1
        }, 1000)
      }).then(
      	res => {
              
              
          // 此处生成新的promise的状态,又此处的执行结果决定
          // 由于此处执行结果未报错,因此promise状态为onResolved,但无返回值
          console.log('onResolved1', res) // 输出 onResolved1 111
        },
        err => {
              
              
          console.log('onRejected1', err)
        },
      ).then(
      	res => {
              
              
          // 执行成功回调函数,无返回值,因此值输出为undefined
          console.log('onResolved2', res) // 输出 onResolved2 undefined
        },
        err => {
              
              
          console.log('onRejected2', err)
        },
      )
      
      // 情况二
      new Promise((resolve, reject) => {
              
              
        setTimeOut(() => {
              
              
          resolve(111) // 情况2
        }, 1000)
      }).then(
      	res => {
              
              
          // 此处生成新的promise的状态,又此处的执行结果决定
          // 由于此处执行return,因此promise状态为onRejected,相当于成功返回222
          console.log('onResolved1', res) // 输出 onResolved1 111
          return 222 // 情况2
        },
        err => {
              
              
          console.log('onRejected1', err)
        },
      ).then(
      	res => {
              
              
          // 执行成功回调函数
          console.log('onResolved2', res) // 输出 onResolved2 222
        },
        err => {
              
              
          console.log('onRejected2', err)
        },
      )
      
      // 情况三
      new Promise((resolve, reject) => {
              
              
        setTimeOut(() => {
              
              
          resolve(111) // 情况3
        }, 1000)
      }).then(
      	res => {
              
              
          // 此处生成新的promise的状态,又此处的执行结果决定
          // 由于此处执行throw,因此promise状态为onRejected
          console.log('onResolved1', res) // 输出 onResolved1 111
          throw 333 // 情况3
        },
        err => {
              
              
          console.log('onRejected1', err)
        },
      ).then(
      	res => {
              
              
          console.log('onResolved2', res)
        },
        err => {
              
              
           // 执行失败回调函数
          console.log('onRejected2', err) // 输出 onRejected2 333
        },
      )
      
      // 情况四
      new Promise((resolve, reject) => {
              
              
        setTimeOut(() => {
              
              
          reject(111) // 情况4
        }, 1000)
      }).then(
      	res => {
              
              
          console.log('onResolved1', res)
        },
        err => {
              
              
          // 此处生成新的promise的状态,又此处的执行结果决定
          // 由于此处执行结果未报错,因此promise状态为onResolved
          console.log('onRejected1', err) // 输出 onRejected1 111
        },
      ).then(
      	res => {
              
              
          // 执行成功回调函数
          console.log('onResolved2', res) // 输出 onResolved2 undefined
        },
        err => {
              
              
          console.log('onRejected2', err)
        },
      )
      
  5. How does promise chain multiple operation tasks (synchronous/asynchronous)?

    • Concatenate multiple tasks through chain calls

    • Note: When connecting asynchronous tasks in series, you need to use new Promise to process the asynchronous tasks

      new Promise ((resolve, reject) => {
              
              
        setTimeOut(() => {
              
              
          console.log('执行任务1(异步)')
          resolve(111)
        }, 1000)
      }).then(
      	res => {
              
              
          console.log('任务1的结果:', res)  // 任务1的结果:111
          
          console.log('执行任务2(同步')
          return 222
        }
      ).then(
      	res => {
              
              
          console.log('任务2的结果:', res)  // 任务2的结果:222
          
          // 使用new Promise对异步任务进行处理
          new Promise((resolve, reject) => {
              
              
              setTimeOut(() => {
              
              
                console.log('执行任务3(异步)')
                reject(333)
              }, 1000)
          })
        }
      ).then(
        res => {
              
              
          ....
        },
      	err => {
              
              
          console.log('任务3的结果:', res)  // 任务3的结果:333
        }
      )
      
  6. Promise exception transmission/penetration?

    • When the promise makes a chain call of then, the callback of catch is made at the end

    • When an exception occurs in any of the previous then, it will be transmitted to the last catch for processing

      new Promise((resolve, reject) => {
              
              
        setTimeOut(() => {
              
              
       	 reject(111)
        }, 1000)
      }).then(
      	res => {
              
              
          ....
        }
        // 此时即使没有指定失败的回调函数,这里相当于执行了以下操作,err值为111
        // err => throw err
      ).then(
      	res => {
              
              
          ....
        }
        // 此时即使没有指定失败的回调函数,这里相当于执行了以下操作,err值为111
        // err => throw err
      ).catch(
      	err => {
              
              
        	console.log(err)  // 111
        }
      )
      
  7. How to break promise chain? (When the promise chain is called, it is interrupted during the process, and the subsequent promise chain calls are not made)

    • At the position of the promise chain that needs to be interrupted, return a promise object in the pending state

      new Promise((resolve, reject) => {
              
              
        setTimeOut(() => {
              
              
       	 resolve(111)
        }, 1000)
      }).then(
      	res => {
              
               .... },
        err => {
              
               .... }
      ).then(
      	res => {
              
               .... },
        err => {
              
               .... }
      ).catch(
        err => {
              
               .... }
        // 需要在此处中断promise链调用,则需要返回一个pendding状态的promise对象,以下
        return new Promise(() => {
              
              })
      ).then(
      	res => {
              
               .... },
        err => {
              
               .... }
      )
      

Guess you like

Origin blog.csdn.net/lhh_gxx/article/details/127964839