下面我试图将一个值,一个数组赋给一个局部变量。我正在调用一个返回数组的函数来获取该值。问题是第二个函数中的Promises
直到数组返回给调用者之后才得到解析。我尝试在Promise.all()
上使用retArray
,但它对我来说无效。当我console.log()
我的someobject
对象后,arrOfTitles
字段永远不会打印出来,因为对SkywalkerTitles()
的调用会返回一个空数组。
您可以运行代码here。
那么如何让someObject.arrOfTitles
从SkywalkerTitles()
获取标题数组?
function SkywalkerTitles(){
let retArray = [];
fetch('https://swapi.co/api/people/')
.then(function(response){
response.json()
.then(function(result){
return result.results[0];
})
.then(function(result){
result.films.forEach(function(film){
fetch(film)
.then(function(response){
response.json().then(function(result){
console.log(result.title);
retArray.push(result.title);
});
});
})
.catch(function(error){
console.log(error)
});
});
})
.catch(function(error){
console.log(error)
});
}
function UseReturnedArray() {
let someObject = { aThing: '', anotherThing: '', arrOfTitles: null };
someObject.aThing = 'Thing One';
someObject.anotherThing = 'Thing Two';
someObject.arrOfTitles = SkywalkerTitles();
console.log('Object With Returned Array:\n\n', JSON.stringify(someObject, null, 2));
}
UseReturnedArray();
答案 0 :(得分:1)
你应该利用async / await,它可以真正清理你的代码并让它更容易理解:
async function SkywalkerTitles () {
let character = await fetch('https://swapi.co/api/people/').then(res => res.json()).then(res => res.results[0])
return await Promise.all(character.films.map(async (film) => {
return await fetch(film).then(res => res.json()).then(res => res.title)
}))
}
async function UseRetrunedArray () {
try {
let someObject = {
aThing: '',
anotherThing: '',
arrOfTitles: await SkywalkerTitles()
}
console.log(someObject)
} catch (e) {
console.error(e)
}
}
UseRetrunedArray()
如果这对您来说很陌生,建议您仔细阅读async
/ await
和Promise
如何协同工作。
答案 1 :(得分:1)
尽管@Svenskunganka的答案是完整且有价值的,但如果你的环境还不支持异步/等待并且你不想使用转换器,则可以选择 - 因为你已经熟悉了Promises,这段代码不应该看起来像外国人:p
你的主要问题是SkywalkerTitles实际上没有返回任何内容(你声称它返回一个空数组,它实际上没有return语句,因此返回的值是undefined
我还删除了.catch
代码,因为你所拥有的代码实际上会导致问题,因为你的代码会处理拒绝,而在代码链的下游,代码会期望数据实际上是有效的!几乎总是只需要一次捕获
function SkywalkerTitles() {
return fetch('https://swapi.co/api/people/').then(function (response) {
return response.json();
}).then(function (result) {
return result.results[0];
}).then(function (result) {
return Promise.all(result.films.map(function (film) {
return fetch(film).then(function (response) {
return response.json();
}).then(function (result) {
return result.title;
});
}));
});
}
function UseReturnedArray() {
SkywalkerTitles().then(function (arrOfTitles) {
var someObject = {
aThing: '',
anotherThing: '',
arrOfTitles: arrOfTitles
};
console.log('Object With Returned Array:\n\n', JSON.stringify(someObject, null, 2));
}).catch(function(reason) {
console.log(reason);
});
}
UseReturnedArray();
请注意,与您的相比,承诺链是如何展平的,并使用Array#map
代替Array#forEach + Array#push