用原生promise特性替代async/await解决异步的方法

发布时间:2023-04-06 12:30

项目开发中用到了async/await,但迁移到另一个平台时,由于该平台的架构问题使得async/await失效(无法使用)。所以必须想一些方法来替代async/await的功能,即在携带请求的异步函数中实现相对同步的方法。


首先,我们得了解promise的一种使用场景:

function runAsync(){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
            console.log('执行!');
        	resolve('数据');
        }, 2000);
    });
    return p;            
}
runAsync()

把异步操作放在promise里,并且包装在一个函数中,让该函数return出这个new出来的promise
这样,在执行该函数后,就会returnpromise对象,从而可以操作promise对象的.then方法

runAsync().then(function(data){
    console.log(data);
    //这里的data,就是刚刚resolve('数据');括号里传过来的东西
    //后面可以用传过来的数据做些其他操作
    //......
});

是不是有点恍然大悟了呢?.then里获取到的data就是promise里异步操作完成后的结果,而在.then里写你在拿到data后需要执行的逻辑,不就解决了因异步拿不到数据的问题了吗~

若我们在一个函数里存在两个请求(异步操作)并且想让他们顺序执行,则可以凭借promise对象的链式操作完成:

runAsync1()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return runAsync3();
})
.then(function(data){
    console.log(data);
});

runAsync1、runAsync2、runAsync3的函数内容为:

function runAsync1(){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
            console.log('异步任务1执行!');
            resolve('数据1');
        }, 1000);
    });
    return p;            
}
function runAsync2(){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
            console.log('异步任务2执行!');
            resolve('数据2');
        }, 2000);
    });
    return p;            
}
function runAsync3(){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
            console.log('异步任务3执行!');
            resolve('数据3');
        }, 2000);
    });
    return p;            
}

就是上面这样,第一个异步操作之后执行第二个,第二个之后执行第三个,当然如果异步操作一样的话,可以自己调用自己,也就是写个递归,后面贴代码

then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数据了,比如:

runAsync1()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return '直接返回数据';  //这里直接返回数据
})
.then(function(data){
    console.log(data); 
});

最后贴一下修改前和修改后的代码,仅供参考:

修改前:

  async getEnergyHouse(dataId) {
      let self = this;
      let datas = {
        xdata: [],
        data: [],
        yAxisName: "",
        legendData: [],
        grid: {
          left: "5%",
          bottom: "13%",
          right: "3%",
          top: "13%",
        },
      };
      let nodeIds = [];
      let nodeidIsChi = [];
      // 获取nodeIds与子数组
      await request.get("xxx", {
          energyType: 1,
          groupType: 1,
        })
        .then((res) => {
          function getNodeids(arr) {
            for (let item of arr) {
              // 取到对应工厂
              if (item.id === dataId) {
                datas.yAxisName = item.name; // 图表名称用工厂名
                self.houseTitle = item.name; // 修改title
                if (item.children.length) {
                  item.children.forEach((chiItem) => {
                    datas.xdata.push(chiItem.name);
                    nodeIds.push(chiItem.id);
                    nodeidIsChi.push(chiItem.children.length); // 若nodeid对应的工厂子级为空,则点击后报错
                  });
                }
                break;
                // 不是对应工厂
              } else {
                // 若子数组为空,则判断下一组工厂数据
                if (item.children.length) {
                  getNodeids(item.children); // 子数组不为空,则用其递归执行该函数
                }
              }
            }
          }
          if (res.success) {
            getNodeids(res.data);
            self.nodeidIsChi = nodeidIsChi;
          }
        })
        .catch(() => {
          this.$Message.error("请求失败");
          self.loading = false;
        });
      self.loading = true;
      let params = {
        nodeType: "meterGroup",
        dimensionType: "nature",
        params: ["xxx"],
      };
      let paramsList = [
        {
          dimension: "hour",
          startTime: moment()
            .add(-1, "hour")
            .add(-1, "hour")
            .format("YYYY-MM-DD HH:mm:ss"),
          name: "上小时",
          type: "bar",
          color: "#0058F4",
        },
        {
          dimension: "day",
          startTime: moment()
            .add(-1, "day")
            .add(-1, "hour")
            .format("YYYY-MM-DD HH:mm:ss"),
          name: "当日",
          type: "bar",
          color: "#00CAFF",
        },
        {
          dimension: "month",
          startTime: moment()
            .add(-1, "month")
            .add(-1, "hour")
            .format("YYYY-MM-DD HH:mm:ss"),
          name: "当月",
          type: "line",
          color: "#10AB8C",
        },
        {
          dimension: "year",
          startTime: moment()
            .add(-1, "year")
            .add(-1, "hour")
            .format("YYYY-MM-DD HH:mm:ss"),
          name: "当年",
          type: "line",
          color: "#F6B32F",
        },
      ];
      Promise.all(
        paramsList.map((item) => {
          return request.post("xxx", {
            ...params,
            dimension: item.dimension,
            startTime: item.startTime,
            nodeIds,
            endTime: moment().add(-1, "hour").format("YYYY-MM-DD HH:mm:ss"),
          });
        })
      )
        .then((reslist) => {
          self.nodeIds = nodeIds;
          self.clickTrue = true;
          reslist.forEach((res, index) => {
            if (res.success) {
              let obj = { name: "", type: "", color: "", list: [] };
              obj.name = paramsList[index].name;
              obj.type = paramsList[index].type;
              obj.color = paramsList[index].color;
              res.data.list.forEach((item) => {
                obj.list.push(item.ydata[1]);
              });
              datas.data.push(obj);
              datas.legendData.push(obj.name);
            }
          });
          self.loading = false;
          self.chartDatas = datas;
        })
        .catch(() => {
          self.clickTrue = true;
          this.$Message.error("请求失败");
          self.loading = false;
        });
    }

修改后:


getEnergyHouse(dataId) {
      let self = this;
      let datas = {
        xdata: [],
        data: [],
        yAxisName: "",
        legend: [],
        grid: {
          left: "5%",
          bottom: "13%",
          right: "3%",
          top: "13%",
        },
      };
      let nodeIds = [];
      let nodeidIsChi = [];

      // 获取nodeIds与子数组
      function runAsync1() {
        var p = request.get("xxxx", {
          energyType: 1,
          groupType: 1,
        });
        return p;
      }

      // 获取图表数据
      function runAsync2(nodeIds) {
        let params = {
          nodeType: "meterGroup",
          dimensionType: "nature",
          params: ["xxx"],
        };
        let paramsList = [
          {
            dimension: "hour",
            startTime: moment()
              .add(-1, "hour")
              .add(-1, "hour")
              .format("YYYY-MM-DD HH:mm:ss"),
          },
          {
            dimension: "day",
            startTime: moment()
              .add(-1, "day")
              .add(-1, "hour")
              .format("YYYY-MM-DD HH:mm:ss"),
          },
          {
            dimension: "month",
            startTime: moment()
              .add(-1, "month")
              .add(-1, "hour")
              .format("YYYY-MM-DD HH:mm:ss"),
          },
          {
            dimension: "year",
            startTime: moment()
              .add(-1, "year")
              .add(-1, "hour")
              .format("YYYY-MM-DD HH:mm:ss"),
          },
        ];
        var p = Promise.all(
          paramsList.map((item) => {
            return request.post("xxxxx", {
              ...params,
              dimension: item.dimension,
              startTime: item.startTime,
              nodeIds,
              endTime: moment().add(-1, "hour").format("YYYY-MM-DD HH:mm:ss"),
            });
          })
        );
        return p;
      }

      runAsync1()
        .then((res) => {
          function getNodeids(arr) {
            for (let item of arr) {
              // 取到对应工厂
              if (item.id === dataId) {
                datas.yAxisName = item.name; // 图表名称用工厂名
                self.houseTitle = item.name; // 修改title
                if (item.children.length) {
                  item.children.forEach((chiItem) => {
                    datas.xdata.push(chiItem.name);
                    nodeIds.push(chiItem.id);
                    nodeidIsChi.push(chiItem.children.length); // 若nodeid对应的工厂子级为空,则点击后报错
                  });
                }
                break;
                // 不是对应工厂
              } else {
                // 若子数组为空,则判断下一组工厂数据
                if (item.children.length) {
                  getNodeids(item.children); // 子数组不为空,则用其递归执行该函数
                }
              }
            }
          }
          if (res.success) {
            getNodeids(res.data);
            self.nodeidIsChi = nodeidIsChi;
            self.loading = true;
          }
          return runAsync2(nodeIds);
        })
        .then((reslist) => {
          self.nodeIds = nodeIds;
          self.clickTrue = true;
          let paramsList = [
            {
              name: "上小时",
              type: "bar",
              color: "#0058F4",
            },
            {
              name: "当日",
              type: "bar",
              color: "#00CAFF",
            },
            {
              name: "当月",
              type: "line",
              color: "#10AB8C",
            },
            {
              name: "当年",
              type: "line",
              color: "#F6B32F",
            },
          ];
          reslist.forEach((res, index) => {
            if (res.success) {
              let obj = { name: "", type: "", color: "", list: [] };
              obj.name = paramsList[index].name;
              obj.type = paramsList[index].type;
              obj.color = paramsList[index].color;
              res.data.list.forEach((item) => {
                obj.list.push(item.ydata[1]);
              });
              datas.data.push(obj);
              datas.legend.push(obj.name);
            }
          });
          self.loading = false;
          self.chartDatas = datas;
        })
        .catch(() => {
          self.clickTrue = true;
          this.$Message.error("请求失败");
          self.loading = false;
        });
    },

THX~

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号