javascript - 使用 contentful CMS 中的 javascript/react 按顺序解决 Promise

标签 javascript reactjs promise es6-promise contentful

我正在尝试按顺序从内容丰富的 CMS 获取一系列数据,完成后初始化我的 React 应用程序。我可以看出我没有正确解决这些 promise ,并且遇到了竞争条件,但我不确定如何解决这个问题。

鉴于以下情况:

this.contentfulClient.getEntry('4KGFPDFY2MZrRWCi4hZj2g')
  .then((entry) => {
    //console.log(entry);
    dataStore.siteData = entry.fields;
  })
  .then(() => {
    this.contentfulClient.getEntries({
      content_type: 'visionsData'
    })
      .then((response) => {
        let visionsArr = [];
        response.items.map((vision) => {
          return visionsArr.push(vision.fields);
        });
        dataStore.visionsData = visionsArr;
        console.log('visions');
      })
  })
  .then(() => {
    this.contentfulClient.getEntries({
      content_type: 'inspirationsData'
    })
      .then((response) => {
        //console.log(response.items);
        let inspirationsArr = [];
        response.items.map((inspiration) => {
          return inspirationsArr.push(inspiration.fields);
        });
        dataStore.inspirationsData = inspirationsArr;
        console.log('inspirations');
      })
      .then(() => {
        console.log('data loaded');
        this.setState({
          dataLoaded: true,
        })
      })
  })
  .catch(console.error)

我想确保我首先获取条目4KGF...,然后将其添加到数据存储中,然后获取visionsData条目,然后将它们添加到dataStore,然后获取 inspirationsData 条目,然后将它们添加到 dataStore,然后将我的应用程序的状态设置为 dataLoaded: true 作为最后一件事。设置该状态后,我应该呈现我的应用程序,如下所示:

render() {
  const { dataLoaded } = this.state;

  if (!dataLoaded) {
    return (<div>LOADING</div>)
  }
  return (
    <Router>
      <div className="App">
        <Route exact path="/" component={Home} />
        <Route exact path="/inspiration" component={Inspiration} />
        <Route exact path="/redesign" component={Redesign} />
        <Route exact path="/visualize" component={Visualize} />
        <Route exact path="/confirmation" component={Confirmation} />
        <Reset />
      </div>
    </Router>
  );
}

但发生的情况是,有时数据集的一部分会先于其他数据集呈现,例如 (inspirationsData),因此 dataLoaded 将被设置为 true,即使visionsData 尚未添加到数据存储中。我知道我可以将每个单独的 getEntries 调用嵌套在之前的 then((response)) 调用中,但是随后我会得到我所认为的嵌套 promise 结构的金字塔类型我正在努力避免。我如何避免这种情况并正确构建我的 promise ?

最佳答案

当其中的操作是异步的并且您希望链按顺序执行时,您需要向 then() 返回一个 promise 。

如果没有 return,或者当返回不是一个 Promise 时,then() 会立即解析,无论内部调用什么异步操作

仅开始示例:

this.contentfulClient.getEntry('4KGFPDFY2MZrRWCi4hZj2g')
  .then((entry) => {
    //console.log(entry);
    dataStore.siteData = entry.fields;
  })
  .then(() => {
     return this.contentfulClient.getEntries({
    //^^^^  return promise to next `then()`

关于javascript - 使用 contentful CMS 中的 javascript/react 按顺序解决 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57296838/

相关文章:

javascript - 简单的点击事件委托(delegate)不起作用

javascript - 拖放 - 拖动时创建新的网格行

javascript - 在 Javascript 中使用 map 数组时未定义的值

reactjs - 如何对 props 和 propTypes 进行分组以减少代码

javascript - rsvp.js 如何使用失败回调链处理被拒绝的 promise

javascript - 在 jQuery 中单击 fadeToggle

javascript - 如何为任何 html 标签分配一个类名?

reactjs - 将组件组合到一个库中

javascript - 使用 D3 解决 Promise

javascript - 避免回调 hell 。 Meteor.call promise