vuejs 应用程序中异步 axios 调用的多个响应的竞争条件

Posted

技术标签:

【中文标题】vuejs 应用程序中异步 axios 调用的多个响应的竞争条件【英文标题】:Race condition with multiple responses from asynchronous axios calls in a vuejs app 【发布时间】:2020-05-27 09:06:17 【问题描述】:

我在我的 Vue.js 应用程序中运行多个 axios.get() 调用。我想调用另一个函数

this.useData()

在所有提取都收到响应之后。我怎样才能做到这一点?我读过 Promise.all()。如果这对我有帮助,请告知如何将 Promise.all 合并到我的代码中。

fetchData() 
  for (let j = 0; j < this.selectedLayers.length; j++) 
    if (this.selectedLayers[j].foo == true) 
      axios
        .get("/maps")
        .then(
          response => 
            console.log(
              "received response for this.selectedLayers[" + j + "]"
            );
            this.selectedLayers[j].data= response.data;
          ,
          error => 
            console.log("error fetching data");
          
        );
    
  
  this.useData();

如果我将asyncawait 添加到我的代码中,如下所示,Vue.js 会响应错误...

不能在异步函数之外使用关键字 'await'

  await this.fetchData();
  this.useData();


async fetchData() 
  for (let j = 0; j < this.selectedLayers.length; j++) 
    if (this.selectedLayers[j].foo == true) 
      await axios
        .get("/maps")
        .then(
          response => 
            console.log(
              "received response for this.selectedLayers[" + j + "]"
            );
            this.selectedLayers[j].data= response.data;
          ,
          error => 
            console.log("error fetching data");
          
        );
    
  

看了论坛这里推荐的第一个答案后,我修改了我的代码如下...

fetchData() 
  return new Promise(resolve => 
    if (this.selectedLayers[j].foo == true) 
      axios
        .get("/maps")
        .then(
          response => 
            console.log(
              "received response for this.selectedLayers[" + j + "]"
            );
            this.selectedLayers[j].data= response.data;
          ,
          error => 
            console.log("error fetching data");
          
        );
  
 );

  let promises = [];
  for (var i = 0; i < this.selectedLayers.length; i++) 
    promises.push(this.fetchData(i));
  

  Promise.all(promises)
    .then(results => 
      this.useData();
    )
    .catch(e => 
      // Handle errors here
    );

Promise.all() 永远不会执行。我想将 Promise.all() 与 axios.get() 结合使用会有细微差别?

【问题讨论】:

看这个问题***.com/questions/31426740/… 【参考方案1】:
async fetchData() 
  let promises = [];
  for (let j = 0; j < this.selectedLayers.length; j++) 
    if (this.selectedLayers[j].foo == true) 
      let promiseRep = axios
        .get("/maps")
        .then(
          response => 
            console.log(
              "received response for this.selectedLayers[" + j + "]"
            );
            this.selectedLayers[j].data= response.data;
          ,
          error => 
            console.log("error fetching data");
          
        );
      promises.push(promiseResp);  
    
  
  try
    const results = await Promise.all(promises); //you can use promise chaining here too
   catch(e)
    console.log(e);
  
  this.useData();

阅读更多关于Promise.all(),

【讨论】:

【参考方案2】:

这是一个你可以尝试的 hacky 解决方案。创建一个名为 counterdata 属性,并在每个 axios 调用完成后递增它。 Watch 这个属性,当它到达所需的计数器时,重置它并调用你的 this.userData() 函数。

【讨论】:

以上是关于vuejs 应用程序中异步 axios 调用的多个响应的竞争条件的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs Test Utils with Jest - 卡住测试异步服务

Vuejs 中的异步和等待

如何在 vuejs 中使用 axios 从数组中发布多个请求?

如何使用 Axios 从 localhost VueJS 调用服务器?

使用 axios 的 Vuejs 页面中的多个并发请求

VueJS/NuxtJs中如何动态调用axios方法