找不到等待 vue.js 异步函数的方法

Nig*_*ght 5 javascript asynchronous vue.js

当我取消注释下面的“return”时,我有以下代码可以工作fetchData。我该如何设置才能等待this.fetchData完成填充项目?我尝试过其他承诺的变体,异步,等待,但无法让它实际工作......

到目前为止,我设置了一个this.items内部fetchData,但我意识到这绝对不是我真正想要做的。它显示了我的调用的前 X 行,因为这样设置,但是调用后应该发生的所有代码都会出现fetchData错误,从尝试执行items.length.

import axios from 'axios';

new Vue({
    el: '#app',
    data() {
        return {
            search: '',
            totalItems: 0,
            items: [],
            loading: true,
            pagination: {},
            headers: [ //some headers
            ],
            items: []
        }
    },
    watch: {
      pagination: {
        handler () {
          this.getDataFromApi()
            .then(data => {
              this.items = data.items
              this.totalItems = data.total
            })
        },
        deep: true
      }
    },
    mounted () {
      this.getDataFromApi()
        .then(data => {
          this.items = data.items
          this.totalItems = data.total
        })
    },
    methods: {
        fetchData() {
            axios.get('/api/v1/translations').then(response => {
                //console.log(response.data)
                this.items = response.data.data
            })

            //the return below is working 100%:
            //return [{id:1,key:1,lg:'en',text:'woopie'}];
        },

        getDataFromApi () {
            this.loading = true
            return new Promise((resolve, reject) => {
                const { sortBy, descending, page, rowsPerPage } = this.pagination

                let items = this.fetchData()
                const total = items.length

                //some code to setup pagination and sort

                setTimeout(() => {
                    this.loading = false
                    resolve({
                    items,
                    total
                    })
                    }, 1000)
            })
        }
    },
})
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

更新的答案

抱歉,在我最初的回答中,我完全错过了这一点:

到目前为止,我设置了一个this.items内部fetchData,但我意识到这绝对不是我真正想要做的。

我的回答假设你确实想要this.items。对于那个很抱歉。

fetchData要在不使用 的情况下获取信息this.items,请使用thenPromise from 上的处理程序axios.get返回一个新的 Promise(记住,thencatch返回 Promise),该 Promise 解析为response.data.data

fetchData() {
//  vvvvvv------------------------
    return axios.get('/api/v1/translations').then(response => {
        return response.data.data;
//      ^^^^^^^^^^^^^^^^^^^^^^^^^
    })
},
Run Code Online (Sandbox Code Playgroud)

这可以写得更简洁:

fetchData() {
    return axios.get('/api/v1/translations').then(response => response.data.data);
},
Run Code Online (Sandbox Code Playgroud)

然后,在 中getDataFromApithen对该 Promise 使用处理程序:

getDataFromApi () {
    this.loading = true
    return this.fetchData().then(items => {
        // You might use this at some stage: const { sortBy, descending, page, rowsPerPage } = this.pagination
        this.loading = false;
        return { items, total: items.length };
    });
}
Run Code Online (Sandbox Code Playgroud)

请注意,处理承诺拒绝的消费者getDataFromApi(例如,catch对其使用处理程序)非常重要。如果您不希望消费者这样做,请不要返回承诺,而使用catchinsidegetDataFromApi代替。


原答案

返回以下承诺axios.get

fetchData() {
//  vvvvvv------------------------
    return axios.get('/api/v1/translations').then(response => {
        //console.log(response.data)
        this.items = response.data.data
    })
},
Run Code Online (Sandbox Code Playgroud)

...然后使用它而不是在以下位置创建一个新的getFromApi

getDataFromApi () {
    this.loading = true
    return this.fetchData().then(() => {
        // You might use this at some stage: const { sortBy, descending, page, rowsPerPage } = this.pagination
        this.loading = false;
        return { items: this.items, total: this.items.length };
    });
}
Run Code Online (Sandbox Code Playgroud)

请记住then(和catch)创造新的承诺;new Promise如果您已经承诺合作,那就没有理由。更多关于该部分的内容:什么是显式承诺构造反模式以及如何避免它?

(请注意,我假设您this.items出于某种原因想要使用该实例。如果不需要,您只想用作回调response.data的返回值axios.get...then并在 中使用它getDataFromApi。)