我有这段代码
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。
答案 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)
});
}