【问题标题】:Problems using values after axios在 axios 之后使用值的问题
【发布时间】:2021-04-18 19:41:10
【问题描述】:

如果这个问题已经在某个地方解决了,我很抱歉,但我无法理解我的问题是什么。在我的场景中,我想在页面最终呈现之前进行 2 个 axios 调用并使用这两个数据响应做一些事情。如果我在模板中输出数据,它是可见的,但是当我想在呈现页面之前使用它时,该值始终是未定义的。 经过一番研究,我想出了以下解决方案:

 created() {
   this.getStuff()

},


methods: {
    async getStuff(){
        this.Stuff1= await this.getSomething1()
        this.Stuff2= await this.getSomething2()
        
        var test = this.Stuff1[2].name 
        console.log(test)
    },

    async getSomething1(){
        const response=await axios.get('http://localhost:4000/apiSomething1');
        return response.data;
    },

    async getSomething2(){
       const response=await axios.get('http://localhost:4000/apiSomething2');
       return response.data;
   },
}

如果我想对这些值做一些事情,例如将它传递给另一个值,它将无法工作,因为 Stuff1 是未定义的。为什么会这样?据我了解,由于await,异步函数应该等到promise 完成,所以在getStuff() 中的2 等待之后,该值应该存在,但事实并非如此。非常感谢您的帮助!

编辑 我尝试了提到的两种解决方案,但遇到了同样的错误。为了清楚起见,我添加了整个代码。

<template>
  <h3>List all players</h3>
  <br />
  <table>
    <tr v-for="player in PlayerAll" :key="player._id">
      <td>{{ player.lastname }}</td>
      <td>{{ player.name }}</td>
      <td>{{ player.birthdate }}</td>
      <td>{{ player.hash }}</td>
      <td>
        <Button
          @click="deleteSpieler(player._id)"
          class="p-button-danger"
          label="Delete Player"
        />
      </td>
    </tr>
  </table>
</template>

<script>
import axios from "axios";

export default {
  data() {
    return {
      PlayerAll: [],
      TeamAll: [],
      Combined: [],
    };
  },

  async created() {
    await this.fetchData();
    var test = this.TeamAll[2].name;
    console.log(test);
  },

  methods: {
    async fetchData() {
      let requests = [];
      try {
        requests = await axios.all([
          axios.get("http://localhost:4000/apiPlayer"),
          axios.get("http://localhost:4000/apiTeam"),
        ]);
      } catch (e) {
        console.error(e);
      }
      this.PlayerAll = requests[0].data;
      this.TeamAll = requests[1].data;
    },
  },
};
</script>

<style scoped>
.btn-success {
  width: 150px;
  height: 150px;
  background: red;
}
</style>

【问题讨论】:

  • 我不知道你在 vue 中一般是如何设置状态的,但只是看看你获取数据的方式,它应该是正确的。
  • 所以我必须为此使用状态管理?我只在传递响应的数据属性中声明了 2 个数组
  • 我认为您还需要在 created() 方法中等待 this.getStuff()。

标签: javascript vue.js axios


【解决方案1】:

我认为你应该使用承诺,因为这意味着一旦 axios 调用完成,你就填充数据,而不是在它发生之前 我看到你在编辑中添加了console.log in created,它肯定不起作用,因为它发生在数据被获取之前 在我提供的代码中,我在表格上添加了 v-if,这样您就可以避免控制台中出现任何错误,以便在获取数据之前呈现它, 我使用 mount 而不是 created 因为它是在 DOM 挂载后调用的,这应该可以工作,如果您有任何问题,请告诉我

<template>
  <h3>List all players</h3>
  <br />
  <table v-if="PlayerAll">
    <tr v-for="player in PlayerAll" :key="player._id">
      <td>{{ player.lastname }}</td>
      <td>{{ player.name }}</td>
      <td>{{ player.birthdate }}</td>
      <td>{{ player.hash }}</td>
      <td>
        <Button
          @click="deleteSpieler(player._id)"
          class="p-button-danger"
          label="Delete Player"
        />
      </td>
    </tr>
  </table>
</template>

<script>
import axios from "axios";

export default {
  data() {
    return {
      PlayerAll: null,
      TeamAll: [],
      Combined: [],
    };
  },

  mounted() {
    this.getStuff();
  },

  methods: {

    getStuff(){
        let vm = this;

        Promise.all([vm.getSomething1(), vm.getSomething2()]).then((values) => {
            vm.PlayerAll= = values[0].data
            vm.TeamAll = values[1].data
        });
    },

    async getSomething1(){
        return await axios.get('http://localhost:4000/apiPlayer');
    },

    async getSomething2(){
        return await axios.get('http://localhost:4000/apiTeam');
    },
};
</script>

<style scoped>
.btn-success {
  width: 150px;
  height: 150px;
  background: red;
}
</style>

【讨论】:

  • 我收到一个参考错误:“未定义响应”并且“无法读取未定义的属性 2”
  • 现在我只收到 Player All 的类型错误“无法读取 null 的属性 2”,而 TeamAll 的值未定义。
  • 在设置前尝试console.log(response)查看api是否一切正确
  • 获取状态 200 和所有正确的值作为数据
  • 下一步将在 console.log(response) 下做 vm.playerAll = response.data;然后是 console.log(vm.playerAll);检查这一步是否被覆盖
【解决方案2】:

created() 方法也应该是异步的。尝试添加 async 关键字。 捕捉错误也是一个好主意;根据我的经验,Axios 会产生毫无意义的错误,甚至不会记录它们。

在从多个端点获取时使用Promise.all(),它适用于Promises,比仅仅发送多个awaits 更好。

async created() {
  await this.fetchData();
}

async fetchData() {
  let requests = [];
  try {
    requests = await Promise.all([axios.get('/api1'), axios.get('/api2')]);
  catch (e) {
    console.error(e);
  }
  this.data1 = requests[0].data;
  this.data2 = requests[1].data;
}

【讨论】:

  • axios.all() 已弃用,取而代之的是 Promise.all()
  • 我试过 axios.all()Promise.all() 但我遇到了同样的问题
  • @lela_98 控制台有错误吗?
  • @motoquick 不,没有任何错误。它只是为我的 console.log(test) 输出 undefined 。访问模板中的值也没有问题。
猜你喜欢
  • 1970-01-01
  • 2020-12-13
  • 2020-12-04
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
相关资源
最近更新 更多