【问题标题】:Nuxt - asyncData with multiple requestsNuxt - 具有多个请求的 asyncData
【发布时间】:2019-06-04 20:08:57
【问题描述】:

在我的应用程序中,我有一个卖家页面,其中显示了该卖家列出的产品。我正在使用 asyncData 来获取页面所需的所有数据(更适合 SEO)

asyncData ({params, app, error }) {

    return app.$axios.$get(`/seller/${params.username}`).then(async sellerRes => {

        let [categoriesRes, reviewsRes, productsRes] = await Promise.all([
            app.$axios.$get(`/categories`),
            app.$axios.$get(`/seller/${params.username}/reviews`),
            app.$axios.$get(`/seller/${params.username}/products`)
        ])

        return {
            seller: sellerRes.data,
            metaTitle: sellerRes.data.name,
            categories: categoriesRes.data,
            reviewsSummary: reviewsRes.summary,
            products: productsRes.data,
        }

    }).catch(e => {
        error({ statusCode: 404, message: 'Seller not found' })
    });
},

虽然这种方法起到了预期的作用,但我不禁认为我做错了。

导航到页面时,nuxt 进度条显示两次(这很奇怪)。

我一直在寻找一段时间,试图在 asyncData 中找到多个请求的示例,但没有太多。

也许我不应该在 asyncData 中调用多个请求?

【问题讨论】:

  • 您是否尝试过 await 获取 app.$axis.$get 而不是返回它?

标签: javascript vue.js vuejs2 nuxt.js


【解决方案1】:

也许是这样?

asyncData ({params, app, error }) {

    return app.$axios.$get(`/seller/${params.username}`).then(sellerRes => {
        return Promise.all([
            app.$axios.$get(`/categories`),
            app.$axios.$get(`/seller/${params.username}/reviews`),
            app.$axios.$get(`/seller/${params.username}/products`)
        ]).then((categoriesRes, reviewsRes, productsRes) => {
            return {
                seller: sellerRes.data,
                metaTitle: sellerRes.data.name,
                categories: categoriesRes.data,
                reviewsSummary: reviewsRes.summary,
                products: productsRes.data,
            }
        })
    }).catch(e => {
        error({ statusCode: 404, message: 'Seller not found' })
    });

},

这是一个承诺链。第一个 Promise 尝试获取有关卖方的信息,如果请求成功,则创建一个新请求,该请求将等待其余信息。

方法asyncData 将等待所有承诺完成并返回调用结果。

【讨论】:

    【解决方案2】:

    实际上,您可以使用async await,它看起来也更干净。

    <template>
      <div class="container">
        <h1>Request 1:</h1>
        <h1>{{ post.title }}</h1>
        <pre>{{ post.body }}</pre>
        <br />
        <h1>Request 2:</h1>
        <h1>{{ todos.title }}</h1>
        <pre>{{ todos.completed }}</pre>
      </div>
    </template>
    
    <script>
    import axios from "axios";
    
    export default {
      async asyncData({ params }) {
        // We can use async/await ES6 feature
        const posts = await axios.get(
          `https://jsonplaceholder.typicode.com/posts/${params.id}`
        );
        const todos = await axios.get(
          `https://jsonplaceholder.typicode.com/todos/${params.id}`
        );
        return { post: posts.data, todos: todos.data };
      },
      head() {
        return {
          title: this.post.title
        };
      }
    };
    </script>
    

    here 是它的工作沙箱。 (不要忘记为:id 路由参数添加一个值)

    【讨论】:

    • 它可以工作,但同步运行 - 如果您想并行运行,请查看下面 Andrew Savetchuk 的答案
    • 当其中一个请求失败时,它会抛出'data' is undefined
    【解决方案3】:

    尝试使用异步等待,这是您可以并行运行两个请求的方法:

    async asyncData ({ $axios }) {
      const [categoriesRes, articlesRes] = await Promise.all([ 
        $axios.get('/fetch/categories'),
        $axios.get('/fetch/articles'),
      ])
    
      return {
        categories: categoriesRes.data,
        articles: articlesRes.data,
      }
    },
    

    【讨论】:

    • 我觉得这个答案值得采纳
    • 这是一个非常酷的例子。我在想我正在并行执行请求,但没有......这就是方式!非常感谢!
    • 如果其中一个请求失败了怎么办?怎么抓?
    猜你喜欢
    • 2021-11-06
    • 2022-11-11
    • 2021-04-01
    • 2019-05-03
    • 1970-01-01
    • 2012-12-08
    • 2021-01-13
    • 2020-09-22
    • 2011-01-18
    相关资源
    最近更新 更多