【问题标题】:How to use a few dispatch in nuxt fetch?如何在 nuxt fetch 中使用一些调度?
【发布时间】:2021-06-24 17:12:27
【问题描述】:

我在 nuxt 中创建了一个站点并从 worpdress api 获取数据。 我有几个商店:home.js、solutions.js、tipo.js、portfolio.js 和 options.js。

在 fetch 中,我检查存储数组是否为空,然后调用调度和填充数组。

export default {
  async fetch({ store }) {
    try {
      if (store.getters['home/home'].length === 0) {
        await store.dispatch('home/fetchHome');
      }
      if (store.getters["solutions/getSolutions"].length === 0) {
        await store.dispatch('solutions/fetchSolutions');
      }
      if (store.getters["tipo/getTipo"].length === 0) {
        await store.dispatch('tipo/fetchTipo');
      }
      if (store.getters["portfolio/getPortfolio"].length === 0) {
        await store.dispatch('portfolio/fetchPortfolio');
      }
      if(store.getters["options/getOptions"].length === 0){
        await store.dispatch('options/fetchOptions');
      }
    } catch (e) {
      console.log(e, 'e no data')
    }
  },
  components: { HomeContacts, PortofolioSlider, Clients, ChiSiamo, Solutions, HomeIntro }
}

但问题是,页面加载时间过长。因为我将调度称为 throw await,我认为这就是问题所在。

如何在 fethc 中调用所有调度,而不是异步但并行?

我看到使用 fetch 优于 asyncData 的优势在于,仅当我第一次加载页面时,我需要稍等片刻,数组将填满,当我从另一个页面到达当前页面时,不会通过api请求,数据会从store中输出。

只是关于 nuxt 在意识形态、如何工作以及什么时候更好用的信息很少。接下来,这会更好。

这个方法不行。

fetch({ store }) {
  const promise1 = new Promise((resolve, reject) => {
    if (store.getters['home/home'].length === 0) {
      resolve(store.dispatch('home/fetchHome'));
    }
  });
  const promise2 = new Promise((resolve, reject) => {
    if (store.getters["solutions/getSolutions"].length === 0) {
      resolve(store.dispatch('solutions/fetchSolutions'));
    }
  });
  const promise3 = new Promise((resolve, reject) => {
    if (store.getters["tipo/getTipo"].length === 0) {
      resolve(store.dispatch('tipo/fetchTipo'));
    }
  });
  const promise4 = new Promise((resolve, reject) => {
    if (store.getters["portfolio/getPortfolio"].length === 0) {
      resolve(store.dispatch('portfolio/fetchPortfolio'));
    }
  });
  const promise5 = new Promise((resolve, reject) => {
    if (store.getters["options/getOptions"].length === 0) {
      resolve(store.dispatch('options/fetchOptions'));
    }
  });
  Promise.all([promise1, promise2, promise3, promise4, promise5])
    .then((data) => console.log(data))
    .catch((error) => console.log(error));

【问题讨论】:

  • Next 上的方法是什么?
  • page is loading to long time = wordpress api,解决方案是制作你自己的wp api,减少功能(bog-standard api将加载所有wp,但根本不输出html)或减少调用或根据需要,另外您可以使用循环来保存几行而不使其异步
  • @LawrenceCherone 所以与前端无关。 Nuxt 和 Next 仅在前端获取数据方面有什么区别?
  • 异步仍然是一个因素
  • @LawrenceCherone async 到目前为止在 Next 和 Nuxt 中是相同的。

标签: promise fetch nuxt.js


【解决方案1】:

假设:

  • store.dispatch() 返回 Promise,
  • 问题的第一次尝试通常是正确的,
  • 目标是并行执行相关调度,

然后:

  • store.dispatch() 序列中排除await

  • store.dispatch()返回的promise累积到一个数组中,

  • 不要使用 new Promise() 包装器,

  • awaitPromise.all(promises) 返回的 Promise。

    export default {
        async fetch({ store }) {
            try {
                let promises = [];
                if (store.getters['home/home'].length === 0) {
                    promises.push(store.dispatch('home/fetchHome'));
                }
                if (store.getters['solutions/getSolutions'].length === 0) {
                    promises.push(store.dispatch('solutions/fetchSolutions'));
                }
                if (store.getters['tipo/getTipo'].length === 0) {
                    promises.push(store.dispatch('tipo/fetchTipo'));
                }
                if (store.getters['portfolio/getPortfolio'].length === 0) {
                    promises.push(store.dispatch('portfolio/fetchPortfolio'));
                }
                if(store.getters['options/getOptions'].length === 0) {
                    promises.push(store.dispatch('options/fetchOptions'));
                }
                let data = await Promise.all(promises);
                console.log(data);
            } catch (e) {
                console.log(e);
            }
        },
        components: { HomeContacts, PortofolioSlider, Clients, ChiSiamo, Solutions, HomeIntro }
    }
    

为方便起见,可以按如下方式进行处理:

export default {
    async fetch({ store }) {
        try {
            let paths = [
                { get: 'home/home',              fetch: 'home/fetchHome' },
                { get: 'solutions/getSolutions', fetch: 'solutions/fetchSolutions' },
                { get: 'tipo/getTipo',           fetch: 'tipo/fetchTipo' },
                { get: 'portfolio/getPortfolio', fetch: 'portfolio/fetchPortfolio' },
                { get: 'options/getOptions',     fetch: 'options/fetchOptions' }
            ];
            let promises = paths.filter(p => store.getters[p.get].length === 0).map(p => store.dispatch(p.fetch));
            let data = await Promise.all(promises);
            console.log(data);
        } catch (e) {
            console.log(e);
        }
    },
    components: { HomeContacts, PortofolioSlider, Clients, ChiSiamo, Solutions, HomeIntro }
}

在代码的其他位置定义paths 数组并将其传递给简化的fetch() 并为其提供配置文件可能更有意义:

    fetch({ store, paths })

如果它仍然不起作用,那么你没有告诉我们一些事情。

【讨论】:

  • 非常感谢。我以同样的方式解决了这个问题。 i.imgur.com/MfS3O3M.png拜托,你能帮我做同样的获取,但要提交。 i.imgur.com/ciBWy0A.png 非常感谢。
  • @serii,我可能可以帮助提交,但您必须通过发布另一个问题来正式提问。
【解决方案2】:

Promise.all 在这里很有用:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
甚至Promise.allSettled(),这取决于你想要做什么:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled

然后,这是在您的页面进行抓取时显示某些内容的问题。您可以在页面顶部使用v-if="$fetchState.pending" 来显示加载程序,同时获取整个内容。

这里与意识形态无关,有 2 个钩子通过阻止页面的呈现 (asyncData()) 或允许您在获取数据时呈现它来进行数据获取 (fetch())。

与框架本身无关,您可以随意做。

【讨论】:

  • 在我看来,问题在于,我习惯于等待。因为第一个 await 应该被执行,然后是第二个,第三个。以及如何向服务器发出并行请求,就像我们在 gulp、parallel 和 series 中所说的那样。
  • 如果我像这样添加承诺,这会解决问题吗? ` const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve( if (store.getters['home/home'].length === 0) { store.dispatch('home /fetchHome'); } ); }, 2000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise2 выполнен'); }, 1500); }); Promise.all([promise1, promise2]) .then((data) => console.log(data[0], data[1])) .catch((error) => console.log(error)); `
  • @serii 我的回答的第一行与您最初的问题有关,即同时进行多个 API 调用。你不应该在这里使用setTimeout,因为这不可靠,async/await 在这里做得更好。
猜你喜欢
  • 2020-11-11
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 2017-03-13
  • 2020-07-16
相关资源
最近更新 更多