Detailed explanation of Promise usage

1 The dilemma of asynchronous code

2 Understand the role of Promise

3 Basic use of Promise

4 Promise status changes

5 Promise instance methods

6 Promise class methods

The Dilemma of Async Processing Code

The previous asynchronous codes were all encapsulated in the following way. The disadvantage is that the order of parameters of the execCode written by each person is different, the user may report errors or something, and there are a lot of things to write.

   // 1.设计这样的一个函数
    function execCode(counter, successCallback, failureCallback) {
      // 异步任务
      setTimeout(() => {
        if (counter > 0) { // counter可以计算的情况 
          let total = 0
          for (let i = 0; i < counter; i++) {
            total += i
          }
          // 在某一个时刻只需要回调传入的函数
          successCallback(total)
        } else { // 失败情况, counter有问题
          failureCallback(`${counter}值有问题`)
        }
      }, 3000)
    }

    // 2.ES5之前,处理异步的代码都是这样封装
    execCode(100, (value) => {
      console.log("本次执行成功了:", value)
    }, (err) => {
      console.log("本次执行失败了:", err)
    })

Promise solves asynchronous processing

1

  function execCode(counter) {
      const promise = new Promise((resolve, reject) => {
        // 异步任务
        setTimeout(() => {
          if (counter > 0) { // counter可以计算的情况 
            let total = 0
            for (let i = 0; i < counter; i++) {
              total += i
            }
            // 成功的回调
            resolve(total)
          } else { // 失败情况, counter有问题
            // 失败的回调
            reject(`${counter}有问题`)
          }
        }, 3000)
      })
      
      return promise
    }


    // const promise = execCode(100)
    // promise.then((value) => {
    //   console.log("成功有了结果: ", value)
    // })
    // promise.catch((err) => {
    //   console.log("失败有了错误: ", err)
    // })

    // const promise2 = execCode(-100)
    // promise2.then(value => {
    //   console.log("成功:", value)
    // })
    // promise2.catch(err => {
    //   console.log("失败:", err)
    // })

    // 执行一次
    execCode(255).then(value => {
      console.log("成功:", value)
    }).catch(err => {
      console.log("失败:", err)
    })

Distinguish between Promise states

1

  // 1.创建一个Promise对象
    const promise = new Promise((resolve, reject) => {
      // 注意: Promise的状态一旦被确定下来, 就不会再更改, 也不能再执行某一个回调函数来改变状态
      // 1.待定状态 pending
      console.log("111111")
      console.log("222222")
      console.log("333333")

      // 2.兑现状态 fulfilled
      resolve()

      // 3.拒绝状态 rejected
      reject()
    })

    promise.then(value => {
      console.log("成功的回调")
    }).catch(err => {
      console.log("失败的回调")
    })

    // executor
    const promise2 = new Promise((resolve, reject) => {

    })

The value of Promise's resolve

1

 const p = new Promise((resolve) => {
      // setTimeout(resolve, 2000)
      setTimeout(() => {
        resolve("p的resolve")
      }, 2000)
    })

    const promise = new Promise((resolve, reject) => {
      // 1.普通值
      // resolve([
      //   {name: "macbook", price: 9998, intro: "有点贵"},
      //   {name: "iPhone", price: 9.9, intro: "有点便宜"},
      // ])

      // 2.resolve(promise)
      // 如果resolve的值本身Promise对象, 那么当前的Promise的状态会有传入的Promise来决定
      // resolve(p)

      // 3.resolve(thenable对象)
      resolve({
        name: "kobe",
        then: function(resolve) {
          resolve(11111)
        }
      })
    })

    promise.then(res => {
      console.log("then中拿到结果:", res)
    })

Promise's then method scheduling

1

   const promise = new Promise((resolve, reject) => {
      resolve("success")
      // reject("failure")
    })

    // promise.then(res => {
    // }).catch(err => {
    // })

    // 1.then参数的传递方法: 可以传递两个参数
    // 这种写法也是可以的
    // promise.then(res => {
    //   console.log("成功回调~", res)
    // }, err => {
    //   console.log("失败回调~", err)
    // })

    promise.then(res => {
      console.log("成功回调~", res)
    })
    promise.then(res => {
      console.log("成功回调~", res)
    })
    promise.then(res => {
      console.log("成功回调~", res)
    })
    promise.then(res => {
      console.log("成功回调~", res)
    })

Promise's catch method scheduling

1

 const promise = new Promise((resolve, reject) => {
      reject("failure")
    })

    promise.then(res => {
      console.log("成功的回调:", res)
    }).catch(err => {
      console.log("失败的回调:", err)
    })

    promise.catch(err => {
      console.log("失败的回调:", err)
    })
    promise.catch(err => {
      console.log("失败的回调:", err)
    })
    promise.catch(err => {
      console.log("失败的回调:", err)
    })
    promise.catch(err => {
      console.log("失败的回调:", err)
    })

The return value of Promise's then

The return value of then is a new promise, and consecutive .then is the return value of the previous then, which is different from the scheduling method of promise.

 const promise = new Promise((resolve, reject) => {
      resolve("aaaaaaa")
      // reject()
    })

    // 1.then方法是返回一个新的Promise, 这个新Promise的决议是等到then方法传入的回调函数有返回值时, 进行决议
    // Promise本身就是支持链式调用
    // then方法是返回一个新的Promise, 链式中的then是在等待这个新的Promise有决议之后执行的
    // promise.then(res => {
    //   console.log("第一个then方法:", res)
    //   return "bbbbbbbb"
    // }).then(res => {
    //   console.log("第二个then方法:", res)
    //   return "cccccccc"
    // }).then(res => {
    //   console.log("第三个then方法:", res)
    // })

    // promise.then(res => {
    //   console.log("添加第二个then方法:", res)
    // })

    // 2.then方法传入回调函数的返回值类型
    const newPromise = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("why")
      }, 3000)
    })

    promise.then(res => {
      console.log("第一个Promise的then方法:", res)
      // 1.普通值
      // return "bbbbbbb"
      // 2.新的Promise
      // return newPromise
      // 3.thenable的对象
      return {
        then: function(resolve) {
          resolve("thenable")
        }
      }
    }).then(res => {
      console.log("第二个Promise的then方法:", res) // undefined
    })

The return value of Promise's catch

What is returned after catch is also a promise, and the return value can also be obtained through then.

As long as the promise is resolved first, no matter how many thens there are, all then will be executed, and catch will not be executed;

As long as the promise decides to reject first, no matter how many thens there are in front of the catch, it will not be executed, and the content in the catch will be executed immediately.

You can enter the catch by throwing an exception. If there is no catch after the exception is thrown, an error will be reported.

 const promise = new Promise((resolve, reject) => {
      // reject("error: aaaaa")
      resolve("aaaaaa")
    })

    // 1.catch方法也会返回一个新的Promise
    // promise.catch(err => {
    //   console.log("catch回调:", err)
    //   return "bbbbb"
    // }).then(res => {
    //   console.log("then第一个回调:", res)
    //   return "ccccc"
    // }).then(res => {
    //   console.log("then第二个回调:", res)
    // })

    // 2.catch方法的执行时机
    promise.then(res => {
      console.log("then第一次回调:", res)
      // throw new Error("第二个Promise的异常error") 
      return "bbbbbb"
    }).then(res => {
      console.log("then第二次回调:", res)
      throw new Error("第三个Promise的异常error")
    }).then(res => {
      console.log("then第三次回调:", res)
    }).catch(err => {
      console.log("catch回调被执行:", err)
    })

    // 中断函数继续执行:
    // 方式一: return
    // 方式二: throw new Error()
    // 方式三: yield 暂停(暂时性的中断)

Promise's finally callback

The catch-all method is a method that will definitely be executed after executing then or catch.

 const promise = new Promise((resolve, reject) => {
      // pending

      // fulfilled
      resolve("aaaa")

      // rejected
      // reject("bbbb")
    })

    promise.then(res => {
      console.log("then:", res)
      // foo()
    }).catch(err => {
      console.log("catch:", err)
      // foo()
    }).finally(() => {
      console.log("哈哈哈哈")
      console.log("呵呵呵呵")
    })


    function foo() {
      console.log("哈哈哈哈")
      console.log("呵呵呵呵")
    }

Promise class method-resolve

Instance methods cannot be used without creating an instance object, the instance object of new xxx.

The class method is a single class name. The xxx method can be used directly.

If you simply need to get an asynchronous parameter, you can directly write a class method to simplify the code.

 // 实例方法
    // const promise = new Promise((resolve) => {
    //   // 进行一系列的操作
    //   resolve("result")
    // })
    // promise.catch

    // 类方法
    const studentList = []
    const promise = Promise.resolve(studentList)

    promise.then(res => {
      console.log("then结果:", res)
    })
    // 相当于
    // new Promise((resolve) => {
    //   resolve("Hello World")
    // })

Promise class method-reject

1

 // 类方法
    const promise = Promise.reject("rejected error")
    promise.catch(err => {
      console.log("err:", err)
    })
    // 相当于 _表示resolve,这个位置一定不能变,因为promise就是2个参数,不要少写
    // new Promise((_, reject) => {
    //   reject("rejected error")
    // })

Promise class method-all method

You need to wait for the previous multiple promises to execute resolve and then use all's then to execute a certain then. In the same way, if a promise in all returns reject, then all's then cannot be executed and will jump to all's catch.

Inside to execute.

 

 // 创建三个Promise
    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        // resolve("p1 resolve")
        reject("p1 reject error")
      }, 3000)
    })

    const p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("p2 resolve")
      }, 2000)
    })
    
    const p3 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("p3 resolve")
      }, 5000)
    })

    // all:全部/所有
    Promise.all([p1, p2, p3]).then(res => {
      console.log("all promise res:", res)
    }).catch(err => {
      console.log("all promise err:", err)
    })

Promise class method-allSettled

This is an intensive class for the all method, and then will definitely be executed. The status of each promise will be returned.

 

  // 创建三个Promise
    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        // resolve("p1 resolve")
        reject("p1 reject error")
      }, 3000)
    })

    const p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("p2 resolve")
      }, 2000)
    })
    
    const p3 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("p3 resolve")
      }, 5000)
    })

    // 类方法: allSettled
    Promise.allSettled([p1, p2, p3]).then(res => {
      console.log("all settled:", res)
    })

Promise class method-race method

One way to test the speed of the code is to use then when there are multiple promises, whichever one executes faster.

The disadvantage is that whether resolve or reject is output first, it will be regarded as completed.

 // 创建三个Promise
    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("p1 resolve")
        // reject("p1 reject error")
      }, 3000)
    })

    const p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        // resolve("p2 resolve")
        reject("p2 reject error")
      }, 2000)
    })
    
    const p3 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("p3 resolve")
      }, 5000)
    })


    // 类方法: race方法
    // 特点: 会等到一个Promise有结果(无论这个结果是fulfilled还是rejected)
    Promise.race([p1, p2, p3]).then(res => {
      console.log("race promise:", res)
    }).catch(err => {
      console.log("race promise err:", err)
    })

Promise class method-any method

It is an optimized version of race. It will only output the result of the first completed resolve.

 // 创建三个Promise
    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        // resolve("p1 resolve")
        reject("p1 reject error")
      }, 3000)
    })

    const p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        // resolve("p2 resolve")
        reject("p2 reject error")
      }, 2000)
    })
    
    const p3 = new Promise((resolve, reject) => {
      setTimeout(() => {
        // resolve("p3 resolve")
        reject("p3 reject error")
      }, 5000)
    })

    // 类方法: any方法
    Promise.any([p1, p2, p3]).then(res => {
      console.log("any promise res:", res)
    }).catch(err => {
      console.log("any promise err:", err)
    })

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/weixin_56663198/article/details/131706534