美文网首页
Promise举例说明

Promise举例说明

作者: 扶得一人醉如苏沐晨 | 来源:发表于2023-12-01 08:59 被阅读0次
    • 异步请求的痛点已经回调地狱是如何产生的
    • 使用callback回调函数的方式封装返回值
    • promise的三种状态以及then的链式调用法改造
    • Promise.all封装多个对象统一处理方案
    • async await异步处理同步化对代码进行重构

    本篇文章适用于有一定Promise基础的同学

    很多同学,对promise比较陌生,只是知道怎么用,无非就是.then().catch(),至于为什么这样用很多同学比较迷茫,网上很多介绍的都太理论化、抽象化,希望能通过这篇文章帮你深入了解一下promise的前因后果。

    一、异步请求的痛点

    下面的举例就以uniapp里面的网络请求uni.request()为例了,如果你做的是微信小程序wx.request()也是一样的,还有jQuery的ajax(),这些都是异步请求,通过success回调函数获取数据的,那有童鞋会问为什么不用vueaxios,因为axios网络请求已经封装promise了。

    onLoad() {
      this.getData()
    },
    methods: {
      getData() {
        // 获取分类列表
        uni.request({
          url: "https://ku.qingnian8.com/dataApi/news/navlist.php",
          success: (res) => {
            // 获取到一个分类的id,查询该分类下面的所有文章
            const id = res.data[0].id
            uni.request({
              url: "https://ku.qingnian8.com/dataApi/news/newslist.php",
              data: {
                cid: id
              },
              success: (res2) => {
                // 获取到一篇文章的id,根据文章id找到该文章下的评论
                const id = res2.data[0].id
                uni.request({
                  url: "https://ku.qingnian8.com/dataApi/news/comment.php",
                  data: {
                    aid: id
                  },
                  success: (res3) => {
                    // 该文章下面的所有评论
                    console.log(res3);
                  }
                })
              }
            })
          }
        })
      }
    }
    
    

    二、使用callback回调函数的方式封装返回值

    onLoad() {
      this.getNavList((res) => {
        // 获取到一个分类的id,查询该分类下面的所有文章
        const id = res.data[0].id
        this.getNewsList(id, (res2) => {
          // 获取到一篇文章的id,根据文章id找到该文章下的评论
          const id = res2.data[0].id
          this.getCommentList(id, (res3) => {
            console.log(res3);
          })
        })
      })
    },
    methods: {
      // 第一个异步步请求---获取分类列表
      getNavList(callback) {
        uni.request({
          url: 'https://ku.qingnian8.com/dataApi/news/navlist.php',
          success: (res) => {
            callback(res)
          }
        })
      },
      // 第二个异步步请求---根据分类id查询该分类下面的所有文章
      getNewsList(id, callback) {
        uni.request({
          url: 'https://ku.qingnian8.com/dataApi/news/newslist.php',
          data: {
            cid: id
          },
          success: (res) => {
            callback(res)
          }
        })
      },
      // 第三个异步步请求---根据文章id查询该文章下面的所有评论
      getCommentList(id, callback) {
        uni.request({
          url: "https://ku.qingnian8.com/dataApi/news/comment.php",
          data: {
            aid: id
          },
          success: (res3) => {
            // 找到该文章下面的所有评论
            callback(res3);
          }
        })
      },
    }
    
    

    三、promise的三种状态以及then的链式调用

    promise是解决异步的方法,本质上是一个构造函数,可以用它实例化一个对象。对象身上有resolve、reject、all,原型上有then、catch方法。promise对象有三种状态: pending-(初识状态/进行中) 、resolvedfulfilled (成功) 、rejected (失败)

    • pending。它的意思是"待定的,将发生的”,相当于是一个初始状态。创建Promise对象时,且没有调用resolve或者是reject方法,相当于是初始状态。这个初始状态会随着你调用resolve,或者是reject函数而切换到另一种状态。
    • resolved。表示解决了,就是说这个承诺实现了。 要实现从pending到resolved的转变,需要在 创建Promise对象时,在函数体中调用了resolve方法
    • rejected。拒绝,失败。表示这个承诺没有做到,失败了。要实现从pending到rejected的转换,只需要在创建Promise对象时,调用reject函数。
    onLoad() {
      // 3. 使用Promise封装
      this.getNavList().then((res) => {
        // 获取到一个分类的id,查询该分类下面的所有文章
        const id = res.data[0].id
        return this.getNewsList(id)
      }).then((res2) => {
        // 获取到一篇文章的id,根据文章id找到该文章下的评论
        const id = res2.data[0].id
        return this.getNewsList(id)
      }).then((res3) => {
        console.log(res3);
      }).catch((error) => {
        // 以上三个异步请求的错误都会在最后一个catch函数里面去捕获
        console.log(error);
      })
    },
    methods: {
      // 第一个Promise异步步请求封装---获取分类列表
      getNavList() {
        return new Promise((resolve, reject) => {
          uni.request({
            url: 'https://ku.qingnian8.com/dataApi/news/navlist.php',
            success: (res) => {
              resolve(res)
            },
            fail: (error) => {
              reject(error)
            },
          })
        })
      },
      // 第二个Promise异步步请求---根据分类id查询该分类下面的所有文章
      getNewsList(id) {
        return new Promise((resolve, reject) => {
          uni.request({
            url: 'https://ku.qingnian8.com/dataApi/news/newslist.php',
            success: (res) => {
              resolve(res)
            },
            fail: (error) => {
              reject(error)
            },
          })
        })
      },
      // 第三个Promise异步步请求---根据文章id查询该文章下面的所有评论
      getCommentList(id) {
        return new Promise((resolve, reject) => {
          uni.request({
            url: 'https://ku.qingnian8.com/dataApi/news/comment.php',
            success: (res) => {
              resolve(res)
            },
            fail: (error) => {
              reject(error)
            },
          })
        })
      },
    }
    

    四、Promise.all封装多个对象统一处理方案(常处理没有依赖关系的异步请求)

    uni.showLoading({
      title: '数据加载中'
    })
    const p1 = this.getNavList()
    const p2 = this.getNewsList()
    const p3 = this.getCommentList()
    Promise.all([p1, p2, p3]).then((resAll) => {
      const [res, res2, res3] = resAll
      console.log(res, res2, res3);
      uni.hideLoading()
    }).catch((error) => {
      // 只要有一个请求失败了,都会被捕获,返回的是第一个报错的信息
    })
    

    五、async await 异步处理同步化对代码进行重构

    // 5. async_await异步处理同步化对代码进行重构
    let res, id
    res = await this.getNavList()
    id = res.data[0].id
    res = await this.getNewsList(id)
    id = res.data[0].id
    res = await this.getCommentList(id)
    console.log(res);
    

    相关文章

      网友评论

          本文标题:Promise举例说明

          本文链接:https://www.haomeiwen.com/subject/ibpzwdtx.html