【问题标题】:Is `async/await` available in Vue.js `mounted`?Vue.js `mounted` 中是否可以使用`async/await`?
【发布时间】:2019-04-30 00:17:32
【问题描述】:

我想在mounted() {}做这样的事情:

await fetchData1();
await fetchData2UsingData1();
doSomethingUsingData1And2();

所以我想知道这是否有效:

async mounted() {
    await fetchData1();
    await fetchData2UsingData1();
    doSomethingUsingData1And2();
},

在我的环境中,它不会引发任何错误,并且似乎运行良好。 但是在这个问题中,生命周期钩子中的async/await没有实现。

https://github.com/vuejs/vue/issues/7209

我找不到更多信息,但实际上是否可用?

【问题讨论】:

    标签: vue.js vuejs2 async-await


    【解决方案1】:

    它会起作用,因为mounted 钩子在组件已经挂载之后被调用,换句话说,它不会在渲染之前等待承诺解决。唯一的问题是,在 Promise 解决之前,您将拥有一个“空”组件。

    如果您需要的是在数据准备好之前不渲染组件,那么您需要在数据中添加一个标志,与 v-if 一起使用,以便在一切准备就绪时渲染组件:

    // in your template
    <div v-if="dataReady">
        // your html code
    </div>
    
    
    // inside your script 
    data () {
        return {
            dataReady: false,
            // other data
        }
    },
    
    async mounted() {
        await fetchData1();
        await fetchData2UsingData1();
        doSomethingUsingData1And2();
        this.dataReady = true;
    },
    

    【讨论】:

    • 对于其他使用 axios 来读取 api 数据的人,我可以使用上述解决方案以及 axios 的 promise 方法:async mounted () { await axios.get('/api/myGetRequest').then(response =&gt; (this.mydata = response)) this.dataReady = true }
    • @Rocky await 为您解决承诺。 axios 提供了一个 async/await 示例。如果你自己处理承诺,那么 async/await 是不必要的。
    • @None 在我的情况下这不是真的。我的响应时间异常缓慢。也许async/await 模式允许更长的响应时间?我不确定规范,但我保证我必须履行承诺。
    • @None 我还应该注意,我正在通过 Vue 的 devServer.proxy 对象使用代理服务器并使用 .pathRewrite 重写路径。而且,我的要求是在加载整个页面之前等待数据。对于我最初的评论,我认为此信息超出了问题的范围,但根据您的评论,我认为可能需要注意。
    • 我无法让asyncasync data () 上工作,所以必须使用async mounted (),如下所示。谢谢。 +1。
    【解决方案2】:

    编辑:如文档中所述,这是一项实验性功能,目前不应在生产应用程序中使用。

    在 vue3 中正确的做法是让你的 setup() 函数像这样异步:

    <script>
    // MyComponent.vue
    export default defineComponent({
    /* ... */
        async setup() {
            await fetchData1();
            await fetchData2UsingData1();
            doSomethingUsingData1And2();
            this.dataReady = true;
        }
    }
    </script>
    

    然后在父级中使用suspense component 来添加这样的后备:

    <template>
        <Suspense>
            <template #default>
                <MyComponent />
            </template>
            <template #fallback>
                Loading...
            </template>
        </Suspense>
    </template>
    

    所以您会在组件加载时看到#fallback 模板,然后在组件准备好时看到组件本身。

    【讨论】:

    • 这应该有一个警告,关于悬念是实验性的,不建议用于生产。我会添加上述警告,但编辑队列目前已满。
    • @AlexisTyler 你说得对,我在答案的顶部添加了一个快速注释。
    【解决方案3】:

    只需使用 $nextTick 来调用异步函数。

    【讨论】:

    • $nextTick 是关于 DOM 渲染,async 是关于异步调用函数(简单来说:不阻塞整个应用程序)。所以,这不可能是一般意义上的解决方案。以下是of.docs 的引用:“在下一个 DOM 更新周期后延迟执行回调。在更改一些数据后立即使用它以等待 DOM 更新。”,
    • 如果您这样做,并且感觉它可以工作,那么您可能会很难调试为什么它在以后不再工作。它(几乎)相当于制作一个await sleep(17)(休眠17ms)。如果组件的加载时间少于 17 毫秒,那就太多了。如果超过 17 毫秒,它将无法工作。而且您实际上无法预测加载需要多少时间,这取决于您的应用程序的复杂性、互联网连接、运行它的计算机的功率、月相...
    猜你喜欢
    • 2016-11-16
    • 1970-01-01
    • 2020-06-11
    • 2019-07-24
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多