无法找到等待vue.js异步功能的方法 [英] Cannot find a way to wait for vue.js async function

查看:93
本文介绍了无法找到等待vue.js异步功能的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在下面的 fetchData 中取消对"return"的注释时,我可以使用以下代码.如何设置它以便等待 this.fetchData 完成填充项目?我已经尝试了其他promise的变体,异步,等待,但无法使其真正起作用...

I have the following code that works when I uncomment the "return" in fetchData below. How can I set it up so I wait for this.fetchData to finish to fill items? I have tried variants of other promises, async, await, but cannot get it to actually work...

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

So far I set a this.items inside fetchData but I realize it's absolutely not what I want to actually do. It shows me the first X lines of my call, because of setting it this way, but all the code that is supposed to happen after the fetchData call is bugging, starting with trying to do 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)
            })
        }
    },
})

推荐答案

更新后的答案:

抱歉,在下面的原始答案中,我完全错过了这一点:

Apologies, in my original answer below I completely missed this:

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

So far I set a this.items inside fetchData but I realize it's absolutely not what I want to actually do.

我的回答是假设您没有想要 this.items .抱歉.

My answer assumed you did want this.items. Sorry about that.

要仅从 fetchData 获取信息而不使用 this.items ,请对 axios的promise使用 then 处理程序.get 返回一个新的promise(记住, then catch 返回promise),该新promise通过 response.data.data 解析:

To just get the info from fetchData without using this.items, use the then handler on the promise from axios.get to return a new promise (remember, then and catch return promises) that resolves with response.data.data:

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

这可以更简洁地写出来:

This can be written more succinctly:

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

然后在 getDataFromApi 中对该承诺使用 then 处理程序:

Then, in getDataFromApi, use a then handler on that 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 };
    });
}

请注意, getDataFromApi 的使用者处理承诺拒绝非常重要(例如,在其上使用 catch 处理程序).如果您不希望消费者这样做,请不要退还承诺,而应在 getDataFromApi 中使用 catch .

Note that it's important that the consumer of getDataFromApi handles promise rejection (e.g., uses a catch handler on it). If you don't want the consumer to do that, don't return the promise, and use a catch within getDataFromApi instead.

原始答案:

返回来自 axios.get 的承诺:

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

...然后使用它而不是在 getFromApi 中创建一个新的:

...and then use it rather than creating a new one in 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 };
    });
}

请记住,然后(和 catch )会创建新的承诺;如果您已经已经承诺可以使用,则没有理由新的承诺.关于该部分的更多信息: 什么是显式promise构建反模式?如何避免?

Remember that then (and catch) create new promises; there's no reason for new Promise if you already have a promise to work with. More on that part: What is the explicit promise construction antipattern and how do I avoid it?

(请注意,由于某些原因,我假设您要在实例上使用 this.items .如果没有,则只想使用 response.data 作为您的 axios.get ... then 回调的返回值,并在 getDataFromApi 中使用它.)

(Note that I'm assuming you want this.items on the instance for some reason. If you didn't, you'd just want to use response.data as the return value of your axios.get...then callback and use it in getDataFromApi.)

这篇关于无法找到等待vue.js异步功能的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆