在侧面图功能中调用Api

时间:2017-08-10 21:31:35

标签: api reactjs text replace redux

我有这段代码

export const callingEveSkill = () => (dispatch, getState) => {

  fetch('https://esi.tech.ccp.is/latest/characters/' + getState().ViewChr.Cid + '/skills/?datasource=tranquility&token=' + getState().ViewChr.At)
    .then(response => response.json())
    .then(json => {

         var SkillList = ( json.skills.map((item, i) => {
             var skill = TypeIdToName(item.skill_id)
            return  {
                skill_id: (skill) ,
                current_skill_level: item.current_skill_level,
                skillpoints_in_skill: item.skillpoints_in_skill
            }

           }))

        return SkillList

    })
    .then( SkillList => {

        dispatch(updateSk( SkillList))
        dispatch(updateSkL('true'))

    })
    .catch(err => {
        console.log("skill error:" + err)
    });
}

在代码中我调用TypeIdToName来调用第三方api以将技能ID更改为可读文本。我看到调用结束,它返回可读的名称,但SkillList显示为undefined。

1 个答案:

答案 0 :(得分:1)

这里的问题是 .map()不会等待Promises履行。以下是关于如何使用Promises编写来解决这个问题的一些想法:

1)!重要重构您的API调用TypeIdToName(),以便它返回一个Promise

有关详细信息,请参阅此处:How do I convert an existing callback API to promises?

2)安装 Q 或允许Promises组合的任何其他库。 ( Promise.all 也可能适合您,具体取决于您的环境)

https://github.com/kriskowal/q

OR

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

3)映射API调用时 - 收集它们返回的promise。

4)使用Q.all()返回只有在完成所有API调用后才能实现的Promise。您可能希望在某些时候限制同时连接的拉动。

所以你的代码看起来像这样:

import Q from 'q';

export const callingEveSkill = () => (dispatch, getState) => {

  fetch('https://esi.tech.ccp.is/latest/characters/' + 
                              getState().ViewChr.Cid + 
            '/skills/?datasource=tranquility&token=' + 
             getState().ViewChr.At
    )
    .then(response => response.json())
    .then(json => {

      //We build the array of promises here
      let promises = json.skills.map((item, i) => {

        //If you did the Step 1 - this should return a Promise object
        //So our .map() has something to work with
        return TypeIdToName(item.skill_id).then(
          (skill) => {
            //As promises fulfil - the array of promises 
            //turns into array of objects like this one
            return {
              skill_id: (skill),
              current_skill_level: item.current_skill_level,
              skillpoints_in_skill: item.skillpoints_in_skill
            }
          }
        );

      })

      //And this promises fulfils when all the others do
      return Q.all(promises);

    })

    //So here we get a SkillList
    .then(SkillList => {

      dispatch(updateSk(SkillList))
      dispatch(updateSkL('true'))

    })
    .catch(err => {
      console.log("skill error:" + err)
    });
}