【问题标题】:How to manage concurrency in client JS?如何在客户端 JS 中管理并发?
【发布时间】:2021-08-17 16:27:40
【问题描述】:

我在客户端 JS 中遇到了一些关于并发问题的问题。有两行代码使用 axios 发送请求。但是下面的代码是在axios请求的回调函数完成之前运行的。

有什么办法可以解决这个并发问题?据我所知,async/await 仅用于 Node.JS 等后端 JS

变量声明:

var chartGroundTank = echarts.init(document.getElementById('chart-ground-tank'));
var chartElevatedTank = echarts.init(document.getElementById('chart-elevated-tank'));

var optionChartGroundTank = {
    series: {
        type: 'liquidFill',
        data: [{
            name: '',
            value: 0,
            // waveAnimation: false,
            amplitude: '4%',
            itemStyle: {
                color: '',
            },
        }]
    }
};

var optionChartElevatedTank = {
    series: {
        type: 'liquidFill',
        data: [{
            name: "",
            value: 0,
            itemStyle: {
                color: ''
            },
            // waveAnimation: false,
            amplitude: '4%',
        }]
    }
};

函数调用:

 axios
    .get("/api/v1/firstAPI")
    .then(function (response) {
      const groundTankData = response.data.sensor1;
      const elevatedTankData = response.data.sensor2;
      setWaterTankColor(groundTankData, optionChartGroundTank, 'gnd'); // the values are 
      setWaterTankColor(elevatedTankData, optionChartElevatedTank, 'elv'); // set slower
      chartGroundTank.setOption(optionChartGroundTank); // this two lines
      chartElevatedTank.setOption(optionChartElevatedTank); // will run earlier
....
)};

函数定义:

function setWaterTankColor(waterLevel, tankType) {
    axios.get("/api/v1/metrics/getData", {
        ...config,
    })
        .then((response) => {
            var { sensor1Info1, sensor1Info2, sensor2Info1, sensor2Info2 } = response.data;
            if (tankType == 'gnd') {
                var color = waterLevel < sensor1Info1 / 100 || waterLevel > sensor1Info2 / 100 ? optionChartGroundTank.series.data[0].itemStyle.color = ["red"] : optionChartGroundTank.series.data[0].itemStyle.color = ["#2f529a"];
            }
            else {
                var color = waterLevel < sensor2Info1 / 100 || waterLevel > sensor2Info2 / 100 ? optionChartElevatedTank.series.data[0].itemStyle.color = ["red"] : optionChartElevatedTank.series.data[0].itemStyle.color = ["#2f529a"];
            }
        });
}

【问题讨论】:

    标签: javascript async-await concurrency promise


    【解决方案1】:

    你应该返回promise,你有setWaterTankColor,然后你可以在回调完成后设置选项。

    function setWaterTankColor(waterLevel, tankType) {
        return axios.get("/api/v1/metrics/getData", {
            ...config,
        })
            .then((response) => {
                var { sensor1Info1, sensor1Info2, sensor2Info1, sensor2Info2 } = response.data;
                if (tankType == 'gnd') {
                    var color = waterLevel < sensor1Info1 / 100 || waterLevel > sensor1Info2 / 100 ? optionChartGroundTank.series.data[0].itemStyle.color = ["red"] : optionChartGroundTank.series.data[0].itemStyle.color = ["#2f529a"];
                }
                else {
                    var color = waterLevel < sensor2Info1 / 100 || waterLevel > sensor2Info2 / 100 ? optionChartElevatedTank.series.data[0].itemStyle.color = ["red"] : optionChartElevatedTank.series.data[0].itemStyle.color = ["#2f529a"];
                }
            });
    }
    

    然后你可以像这样使用函数:

     axios
        .get("/api/v1/firstAPI")
        .then(function (response) {
          const groundTankData = response.data.sensor1;
          const elevatedTankData = response.data.sensor2;
          setWaterTankColor(groundTankData, optionChartGroundTank, 'gnd').then(function() { chartGroundTank.setOption(optionChartGroundTank); });
          setWaterTankColor(elevatedTankData, optionChartElevatedTank, 'elv').then(function() { chartElevatedTank.setOption(optionChartElevatedTank); });
    ....
    )};
    

    【讨论】:

      【解决方案2】:

      这两行代码运行得更早,因为它们是同步函数。 为了让它们稍后运行,您可以先等待函数setWaterTankColor。 您可以在您的情况下使用 async/await 。我还添加了trycatch 来捕获 API 调用中的错误。

      (async function run() {
        try {
          const response = await axios.get("/api/v1/firstAPI");
          const groundTankData = response.data.sensor1;
          const elevatedTankData = response.data.sensor2;
          await setWaterTankColor(groundTankData, optionChartGroundTank, "gnd");
          await setWaterTankColor(elevatedTankData, optionChartElevatedTank, "elv");
          chartGroundTank.setOption(optionChartGroundTank);
          chartElevatedTank.setOption(optionChartElevatedTank);
        } catch (err) {
          console.log(err);
        }
      })();
      
      async function setWaterTankColor(waterLevel, tankType) {
        try {
          const response = axios.get("/api/v1/metrics/getData", {
            ...config,
          });
      
          const { sensor1Info1, sensor1Info2, sensor2Info1, sensor2Info2 } =
            response.data;
      
          if (tankType == "gnd") {
            var color =
              waterLevel < sensor1Info1 / 100 || waterLevel > sensor1Info2 / 100
                ? (optionChartGroundTank.series.data[0].itemStyle.color = ["red"])
                : (optionChartGroundTank.series.data[0].itemStyle.color = [
                    "#2f529a",
                  ]);
          } else {
            var color =
              waterLevel < sensor2Info1 / 100 || waterLevel > sensor2Info2 / 100
                ? (optionChartElevatedTank.series.data[0].itemStyle.color = ["red"])
                : (optionChartElevatedTank.series.data[0].itemStyle.color = [
                    "#2f529a",
                  ]);
          }
        } catch (err) {
          throw err;
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-13
        • 1970-01-01
        • 2011-09-27
        • 1970-01-01
        相关资源
        最近更新 更多