繁体   English   中英

Promise.then不是一个函数 - 在React中处理多个API调用

[英]Promise.then is not a function - handling multiple API calls in React

我正在使用react-select来自动完成搜索栏中的选项。 搜索栏以两种类别之一显示结果,具体取决于它命中的API端点。

现在,它可以处理来自某一点或另一点的数据,但是我无法将数据从两个端点返回到react-select的loadOptions参数。

这个关于多个API调用的答案 ,我决定使用promises一次返回所有数据,但是我得到错误Uncaught TypeError: promise.then is not a function at Async.loadOptions

这是我的loadOptions代码:

const getAsync = (tripId, destinationIndex, input) => {
  if (!input) {
    return { options: [] }
  }

  function getMusement(input) {
    return new Promise(function(resolve, reject) {
      TVApi.musement.autocomplete(input)
        .then((m) => {
          const musementOptions = m.map(musementToOption).slice(0, 4)
          return resolve(musementOptions)
        })
    })
  }

  function getFourSquare(tripId, destinationIndex, input) {
    return new Promise(function(resolve, reject) {
      TVApi.spot.autocomplete(tripId, destinationIndex, input)
        .then((fs) => {
          const fsOptions = fs.map(spotToOption).slice(0, 4)
          return resolve(fsOptions)
        })
    })
  }

  return Promise.all([getMusement(input), getFourSquare(tripId, destinationIndex, input)])
    .then((allData) => {
      const merged = [].concat.apply([], allData)
      console.log(JSON.stringify(merged)) // logs out with correct data
      return {options: merged}
    })
}

您的问题是getAsync并不总是返回一个promise,因此您无法将getAsync .then(…)到每个调用。 如果没有输入,则返回一个普通对象 - 而是需要返回使用该对象解析的promise:

if (!input) {
   return Promise.resolve({ options: [] });
}

所以事实证明if语句导致了错误:

if (!input) {
  return {options: []}
}

但我不知道为什么会这样。 如果有人可以解释原因,那么对未来的问题会有所了解。

这是我遵循@ Bergi建议避免Promise Constructor antipattern的解决方案

const loadOptions = (tripId, destinationIndex, input) => {

  function getMusement(input) {
    return TVApi.musement.autocomplete(input)
      .then((m) => {
        const musementOptions = m.map(musementToOption).slice(0, 3)
        return musementOptions
      })
  }

  function getFourSquare(tripId, destinationIndex, input) {
    return TVApi.spot.autocomplete(tripId, destinationIndex, input)
      .then((fs) => {
        const fsOptions = fs.map(fsToOption).slice(0, 2)
        return fsOptions
      })
  }

  return Promise.all([getMusement(input), getFourSquare(tripId, destinationIndex, input)])
    .then((allData) => {
      const merged = [].concat.apply([], allData)
      return {options: merged}
    })
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM