嵌套承诺 - 映射函数内的映射函数
Nested Promises - Map function inside a map function
基本上我有一个大数组,对象值如下:
[{
- Champion Name
- [Another Array with Skins information]
}]
所以我想做的是 运行 第二个数组中的映射函数,为这些皮肤中的每个人获取一个值,所以我所做的是。
const got = require('got');
const cheerio = require('cheerio');
const fs = require('fs').promises;
const getSkinData = async champSkins => {
const data = JSON.parse(champSkins);
const handleMap = skin => {
return new Promise(async (resolve, reject) => {
try {
const name = skin.split(' ').join('_');
const { body } = await got(`https://lol.gamepedia.com/${name}`);
const $ = cheerio.load(body);
const skinLink = $('.InfoboxSkin img').attr('src') || '';
const skinInfo = {
skinName: skin,
skinLink
};
resolve(skinInfo);
} catch (err) {
console.error(err.message);
}
});
};
Promise.all(
data.map(async ({ skins }) => {
return Promise.all(
skins.map(skin => {
return handleMap(skin);
})
);
})
).then(data => console.log(data));
};
module.exports = getSkinData;
但它实际上没有用,我无法访问数据,最后承诺中的 console.log 甚至没有 运行。
知道怎么做或者有更好的方法吗?
编辑#1
基本上 'skins' 每个冠军都是一个字符串数组,例如:
[ 'Aatrox',
'Justicar Aatrox',
'Mecha Aatrox',
'Sea Hunter Aatrox'
'Blood Moon Aatrox'
'Blood Moon Aatrox
'Victorious Aatrox' ]
[ 'Ahri',
'Dynasty Ahri',
'Midnight Ahri',
'Foxfire Ahri',
'Popstar Ahri',
'Challenger Ahri',
'Academy Ahri',
'Arcade Ahri',
'Star Guardian Ahri
'K/DA Ahri',
'K/DA Ahri Prestige
'Elderwood Ahri' ]
皮肤就是数组的每个值
从抓取中返回的值只是每个皮肤的 link
const getSkinData = async champSkins => {
const data = JSON.parse(champSkins);
// async that returns promise is a double promise, you only need async
const handleMap = async skin => {
try {
const name = skin.split(" ").join("_");
const { body } = await got(`https://lol.gamepedia.com/${name}`);
const $ = cheerio.load(body);
const skinLink = $(".InfoboxSkin img").attr("src") || "";
const skinInfo = {
skinName: skin,
skinLink
};
// changed resolve to return
return skinInfo;
} catch (err) {
console.error(err.message);
}
};
return await Promise.all(data.map(({ skins }) => Promise.all(skins.map(skin => handleMap(skin)))));
};
异步函数 return 一个使用 return 值解析的承诺,因此 return 从异步函数中获取承诺是多余的,最终会导致嵌套承诺。此外,您不必在异步函数中使用 .then
因为您可以 await
承诺。详细了解 Promises and async/await。
基本上我有一个大数组,对象值如下:
[{
- Champion Name
- [Another Array with Skins information]
}]
所以我想做的是 运行 第二个数组中的映射函数,为这些皮肤中的每个人获取一个值,所以我所做的是。
const got = require('got');
const cheerio = require('cheerio');
const fs = require('fs').promises;
const getSkinData = async champSkins => {
const data = JSON.parse(champSkins);
const handleMap = skin => {
return new Promise(async (resolve, reject) => {
try {
const name = skin.split(' ').join('_');
const { body } = await got(`https://lol.gamepedia.com/${name}`);
const $ = cheerio.load(body);
const skinLink = $('.InfoboxSkin img').attr('src') || '';
const skinInfo = {
skinName: skin,
skinLink
};
resolve(skinInfo);
} catch (err) {
console.error(err.message);
}
});
};
Promise.all(
data.map(async ({ skins }) => {
return Promise.all(
skins.map(skin => {
return handleMap(skin);
})
);
})
).then(data => console.log(data));
};
module.exports = getSkinData;
但它实际上没有用,我无法访问数据,最后承诺中的 console.log 甚至没有 运行。
知道怎么做或者有更好的方法吗?
编辑#1
基本上 'skins' 每个冠军都是一个字符串数组,例如:
[ 'Aatrox',
'Justicar Aatrox',
'Mecha Aatrox',
'Sea Hunter Aatrox'
'Blood Moon Aatrox'
'Blood Moon Aatrox
'Victorious Aatrox' ]
[ 'Ahri',
'Dynasty Ahri',
'Midnight Ahri',
'Foxfire Ahri',
'Popstar Ahri',
'Challenger Ahri',
'Academy Ahri',
'Arcade Ahri',
'Star Guardian Ahri
'K/DA Ahri',
'K/DA Ahri Prestige
'Elderwood Ahri' ]
皮肤就是数组的每个值
从抓取中返回的值只是每个皮肤的 link
const getSkinData = async champSkins => {
const data = JSON.parse(champSkins);
// async that returns promise is a double promise, you only need async
const handleMap = async skin => {
try {
const name = skin.split(" ").join("_");
const { body } = await got(`https://lol.gamepedia.com/${name}`);
const $ = cheerio.load(body);
const skinLink = $(".InfoboxSkin img").attr("src") || "";
const skinInfo = {
skinName: skin,
skinLink
};
// changed resolve to return
return skinInfo;
} catch (err) {
console.error(err.message);
}
};
return await Promise.all(data.map(({ skins }) => Promise.all(skins.map(skin => handleMap(skin)))));
};
异步函数 return 一个使用 return 值解析的承诺,因此 return 从异步函数中获取承诺是多余的,最终会导致嵌套承诺。此外,您不必在异步函数中使用 .then
因为您可以 await
承诺。详细了解 Promises and async/await。