15、回调地狱终结者Promise

1、获取异步函数(如网络请求wx.request({…})wx.getSystemInfo({…}))有success、fail回调函数的返回数据。

         方法一:通过把this传出,来设置data中的hhOutPut的变量

    方法二:把success改成箭头函数,格式success:(res)=>

       修改后可以直接用this

Promise引入

1、假如异步函数中,如果依次要请求5次,第一次请求成功后才能请求第二次,第二次请求成功后才能请求第三次。以此类推,代码应该是这样写:

这样越写会越多,嵌套的代码也会增多。人们给它命名为:回调地狱

2Promise就是基于解决这种回调地狱问题产生的,它可以让代码看起来更加扁平,也可以实现1中的获取异步函数的值。具体写法:

写一个Promise 回调函数

1、最简单的回调函数:把1中异步网络请求的代码改写成Promise回调函数

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

      //把需要异步处理的函数放在这里

      wx.request({

        url: 'https://294k1p5882.qicp.vip/hhtest.aspx',

        data: {

          keyword: InputStr,

          keyword1: InputDataS

        },

        header: {

          'content-type': 'application/json'

        },

        success: (res) => {

          resolve(res)//成功的时候把成功的resresolve传出

        },

        fail:(error)=> {

          reject(error)//失败的时候把失败的errorreject传出

        }

      })

    })

    //这里处理异步运行完后的结果

    promise.then((res) => {

      //res一定要跟上面resolve(res)的对应,且顺序不能变,先reserror

      this.setData({ hhOutPut: res.data })//promise的处理结果中可以直接用this

    }, (error) => {

      //error一定要跟上面reject(error)对应,且顺序不能变,先reserror

    })

2、假如箭头函数只有一个参数(res)的时候,res外面的括号可以去掉

     假如箭头函数体你只有一方处理代码(resolves(res),函数体的花括号也是可以去掉的

    所以以上代码可以改写成这样:

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

      //把需要异步处理的函数放在这里

      wx.request({

        url: 'https://294k1p5882.qicp.vip/hhtest.aspx',

        data: {

          keyword: InputStr,

          keyword1: InputDataS

        },

        header: {

          'content-type': 'application/json'

        },

        success: res => resolve(res),//成功的时候把成功的resresolve传出

        fail: error => reject(error)//失败的时候把失败的errorreject传出

      })

    })

    //这里处理异步运行完后的结果

    promise.then(

      res => this.setData({ hhOutPut: res.data }),//res一定要跟上面resolve(res)的对应,且顺序不能变,先reserror  promise的处理结果中可以直接用this

      error => console.log(error)

      //error一定要跟上面reject(error)对应,且顺序不能变,先reserror

    )

继续改进1:把Promise 作为函数返回

1、自定义异步请求函数

  //自定义函数,返回Promise对象,传入网络请求的相关参数,可带默认参数路method

  httpRequest(urlTemp,InputStrTemp, InputDataSTemp, method = 'GET') {

    return new Promise((resolve, reject) => {

      wx.request({

        url: urlTemp,

        data: {

          keyword: InputStrTemp,

          keyword1: InputDataSTemp

        },

        header: {

          'content-type': 'application/json'

        },

        success: (res) => {

          resolve(res)//成功的时候把成功的resresolve传出

        },

        fail: (error) => {

          reject(error)//失败的时候把失败的errorreject传出

        }

      })

    })

  },

2、调用:

  BtnWeb: function (even) {

    const Promise1 = this.httpRequest('https://294k1p5882.qicp.vip/hhtest.aspx', InputStr, InputDataS)

    Promise1.then((res) => {

      //res一定要跟上面resolve(res)的对应,且顺序不能变,先reserror

      this.setData({ hhOutPut: res.data })//

    }, (error) => {

      //error一定要跟上面reject(error)对应,且顺序不能变,先reserror

    })

  },

3、在第一次调用成功后调用第二次,第二次成功后调用第三次

  BtnWeb: function (even) {

    //调用第一次

    const Promise1 = this.httpRequest('https://294k1p5882.qicp.vip/hhtest.aspx', InputStr, InputDataS)

    Promise1.then((res) => {

      //第一次成功后调用第二次

      const Promise2 = this.httpRequest('https://294k1p5882.qicp.vip/hhtest.aspx', InputStr, InputDataS)

      Promise2.then((res) => {

        //第二次成功后调用第三次

        const Promise2 = this.httpRequest('https://294k1p5882.qicp.vip/hhtest.aspx', InputStr, InputDataS)

        Promise2.then((res) => {

          this.setData({ hhOutPut: res.data })//

        }, (error) => {

        })

      }, (error) => {

      })

    }, (error) => {

    })

},

4、虽然是可以调用成功,但是仍然没解决回调地狱问题

继续改进2 Promise真正解决回调地狱

1、调用方法

    const Promise1 = this.httpRequest('https://294k1p5882.qicp.vip/hhtest.aspx', InputStr, InputDataS)

      .then((res) => {

        //第一次调成功的then下,调用第二次,用return返回Promise对象

        return this.httpRequest('https://294k1p5882.qicp.vip/hhtest.aspx', InputStr, InputDataS)

      }, (error) => {

      })//以上的所有代码是调用2次后返回的Promise对象

      .then((res) => {

         //第二次调成功的then下,调用第三次,用return返回Promise对象

        return this.httpRequest('https://294k1p5882.qicp.vip/hhtest.aspx', InputStr, InputDataS)

      }, (error) => {

      })//以上的所有代码是调用3次后返回的Promise对象

      .then((res) => {

        //第二次调成功的then下,修改页面数据

        this.setData({ hhOutPut: res.data })

      }, (error) => {

      })

继续改进3 async/await的配合使用

1、原生的小程序并不支持async的使用:

2、到云盘下载支持文件

3、发到utils文件夹中,并在页面的js中引入

const regeneratorRuntime=require('../utils/runtime.js')

4、引入成功后,编译即可通过

5、添加需要异步处理的函数,若每个调用的都resolve,则发现输出结果跟我们要的一样

const regeneratorRuntime = require('../../utils/runtime.js')

Page({

  data: {

  },

  BtnTest: function (even) {

    this.TestAsync()

  },

  async TestAsync() {

    try {

      console.log('1开始');

      let ret1 = await this.fun1(1)

      console.log('1结束2开始');

      let ret2 = await this.fun2(1)

      console.log('2结束3开始');

      let ret3 = await this.fun3(1)

      console.log('3结束');

    }

    catch (e) {

      console.log('---出错---', e);

    }

  },

  fun1(flag) {

    return new Promise((resolve, reject) => {

      if (flag > 0) {

        resolve('1-ok')

      } else {

        reject('1-ng')

      }

    })

  },

  fun2(flag) {

    return new Promise((resolve, reject) => {

      if (flag > 0) {

        resolve('2-ok')

      } else {

        reject('2-ng')

      }

    })

  },

  fun3(flag) {

    return new Promise((resolve, reject) => {

      if (flag > 0) {

        resolve('3-ok')

      } else {

        reject('3-ng')

      }

    })

  }

})

6、假如第二个异步处理fun2时,reject结果。会发现:第三个不执行,调到catch报错

7、假如要在报错结果出做更复杂的逻辑处理可以这样做:

const regeneratorRuntime = require('../../utils/runtime.js')

Page({

  data: {

  },

  BtnTest: function (even) {

    let retAsync = this.TestAsync()

  },

  async TestAsync() {

    try {

      console.log('1开始');

      let ret1 = await this.fun1(1).catch(err => Promise.reject("fun1异常"))

      console.log('1结束2开始');

      let ret2 = await this.fun2(-1).catch(err => Promise.reject("fun2异常"))

      console.log('2结束3开始');

      let ret3 = await this.fun3(1).catch(err => Promise.reject("fun3异常"))

      console.log('3结束');

    }

    catch (e) {

      switch (e) {

        case "fun1异常":

          console.log('---出错1---', e);

          break;

        case "fun2异常":

          console.log('---出错2---', e);

          break;

        case "fun3异常"

          console.log('---出错3---', e);

          break;

      }

    }

  },

  fun1(flag) {

    return new Promise((resolve, reject) => {

      if (flag > 0) {

        resolve('1-ok')

      } else {

        reject('1-ng')

      }

    })

  },

  fun2(flag) {

    return new Promise((resolve, reject) => {

      if (flag > 0) {

        resolve('2-ok')

      } else {

        reject('2-ng')

      }

    })

  },

  fun3(flag) {

    return new Promise((resolve, reject) => {

      if (flag > 0) {

        resolve('3-ok')

      } else {

        reject('3-ng')

      }

    })

  }

})

继续改进3 async函数的返回值给调用方

  BtnTest: function (even) {

    this.TestAsync().then(function (res1) {

      if (res1.indexOf("全部完成") >= 0) {

        console.log(res1); //asyn函数全部执行成功并返回

      } else {

        console.log(res1);  //asyn函数执行中间失败并返回

      }

    })

  },

  async TestAsync() {

    try {

      console.log('1开始');

      let ret1 = await this.fun1(1).catch(err => Promise.reject("fun1异常"))

      console.log('1结束2开始');

      let ret2 = await this.fun2(-1).catch(err => Promise.reject("fun2异常"))

      console.log('2结束3开始');

      let ret3 = await this.fun3(1).catch(err => Promise.reject("fun3异常"))

      console.log('3结束');

      return "全部完成"

    }

    catch (e) {

      switch (e) {

        case "fun1异常":

          console.log('---出错1---', e);

          return "1个出错了"

          break;

        case "fun2异常":

          console.log('---出错2---', e);

          return "2个出错了"

          break;

        case "fun3异常":

          console.log('---出错3---', e);

          return "3个出错了"

          break;

      }

    }

  },

循环async函数

  BtnTest1: function (even) {

    let aaa = this.xunhuan(1, 3) //调用循环,从第一次开始,总共要执行3

  },

  xunhuan: function (currentIndex, AllCount) {

    var that = this

    that.TestAsync1(currentIndex).then(function (res1) {

      if (res1.indexOf("整次成功") >= 0) {

        if (currentIndex < AllCount) {

          // 递归调用继续下一次

          currentIndex = currentIndex + 1

          that.xunhuan(currentIndex, AllCount)

        } else {

          return "全部完成"

        }

      } else {

        console.log(res1);

        return res1

      }

    })

  },

  //调用promis fun4fun5

  async TestAsync1(index) {

    try {

      console.log(index + '--4开始');

      let ret1 = await this.fun4(1).catch(err => Promise.reject(index + "--fun4异常"))

      console.log(index + '--4结束5开始');

      let ret2 = await this.fun5(1).catch(err => Promise.reject(index + "--fun5异常"))

      console.log(index + '--5结束');

      return index + "--整次成功"

    }

    catch (e) {

      switch (e) {

        case index + "--fun4异常":

          console.log(index + '---出错4---', e);

          break;

        case index + "--fun5异常":

          console.log(index + '---出错5---', e);

          break;

      }

      return index + "整次失败"

    }

  },

  //定时2sresolvereject

  fun4(flag) {

    return new Promise((resolve, reject) => {

      if (flag > 0) {

        setTimeout(function () {

          resolve('4-ok')

        }, 2000);

      } else {

        setTimeout(function () {

          reject('4-ng')

        }, 2000);

      }

    })

  },

  //定时2sresolvereject

  fun5(flag) {

    return new Promise((resolve, reject) => {

      if (flag > 0) {

        setTimeout(function () {

          resolve('5-ok')

        }, 2000);

      } else {

        setTimeout(function () {

          reject('5-ng')

        }, 2000);

      }

    })

  },

循环中使用Await

 async TestAsync1() {

    try {

      console.log('--4开始');

      let ret1 = await this.GetGameDataBase().catch(err => Promise.reject("GetGameDataBase异常"))

      let Allne = ret1.data

      let selectNe = []

      for (const item of Allne{

        console.log('--4结束5开始', item.TouXianFileID);

        let ret2 = await this.downloadTouXian(item.TouXianFileID).catch(err => Promise.reject("downloadTouXian异常"))

        console.log('89', ret2)

      }

      //不用以下循环,否则会异步-----><<<<<<<<<<<<<<<<<<<<重点<<<<<<<<<<<<<<<<<

      // Allne.forEach(async item => {

      //   console.log('--4结束5开始', item.TouXianFileID);

      //   let ret2 = await this.downloadTouXian(item.TouXianFileID) .catch(err => Promise.reject("downloadTouXian异常"))

      //   console.log('89', ret2)

      // })

      console.log('--5结束');

      // return "--整次成功"

    } catch (e{

      switch (e{

        case "GetGameDataBase异常":

          console.log(e);

          break;

        case "downloadTouXian异常":

          console.log(e);

          break;

      }

      return "整次失败"

    }

  },

  //定时2sresolvereject

  GetGameDataBase() {

    return new Promise((resolve, reject) => {

      dbGameCollection.orderBy('Score', 'asc').get({

        success: function (res) {

          resolve(res)

        },

        fail: err => {

          reject(err)

        }

      })

    })

  },

  //定时2sresolvereject

  downloadTouXian(TouXianFileID) {

    return new Promise((resolve, reject) => {

      wx.cloud.downloadFile({

        fileID: TouXianFileID,

        success: resTouXianFileID => {

          resolve(resTouXianFileID)

        },

        fail: errTouXianFileID => {

          reject(errTouXianFileID)

        }

      })

    })

  },

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
终端终结者是一个在Ubuntu上使用的终端模拟器。您可以按照以下步骤来安装和使用终端终结者: 1. 打开终端(按下Ctrl+Alt+T)。 2. 运行以下命令来安装终端终结者sudo apt-get install terminator 3. 安装完成后,您可以通过在应用程序菜单中搜索“终端终结者”或在终端中运行“terminator”命令来打开它。 4. 一旦打开终端终结者,您可以右键单击终端窗口,并选择“水平”或“垂直”方向来扩展一个新的终端。这样,您就可以在一个窗口中同时操作多个终端。 如果遇到终端终结者无响应的问题,可能是由于系统默认的Python版本设置为Python 3导致的。这时您可以按照以下方法解决: 1. 打开终端终结者的启动文件。您可以通过运行以下命令来找到启动文件的位置:which terminator 2. 打开启动文件并进行编辑。例如,如果启动文件是“/usr/bin/terminator”,则可以运行以下命令来编辑它:sudo nano /usr/bin/terminator 3. 在打开的文件中,找到以“#!/usr/bin/python”开头的一行,并将其修改为“#!/usr/bin/python2”。 4. 保存并关闭文件。 5. 再次尝试运行终端终结者,应该可以正常启动了。 希望这些信息能够帮助您解决问题。如果您有任何其他相关问题,请随时提问。 相关问题: 1. 如何卸载终端终结者? 2. 如何在终端终结者中创建自定义布局? 3. 如何在终端终结者中设置快捷键?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值