Javascript ES6承诺使用嵌套的Array.map()
我正在处理一个项目,其中我希望其中一个函数返回修改后的“player”对象 想象一下,如果你有一个等于的播放器(下面不是真正的代码,但逻辑是相同的): 和stats(对象数组)等于:Javascript ES6承诺使用嵌套的Array.map(),javascript,node.js,Javascript,Node.js,我正在处理一个项目,其中我希望其中一个函数返回修改后的“player”对象 想象一下,如果你有一个等于的播放器(下面不是真正的代码,但逻辑是相同的): 和stats(对象数组)等于: [ { id: 1, val: 400 } { id: 2, val: 590 } ] 问题是,当我执行嵌套映射(.map())时,我的播放器以某种方式返回(解决)的速度比map函数结束迭代的速度快。但是,我希望它只在
[
{
id: 1,
val: 400
}
{
id: 2,
val: 590
}
]
问题是,当我执行嵌套映射(.map())时,我的播放器以某种方式返回(解决)的速度比map函数结束迭代的速度快。但是,我希望它只在所有迭代完成后返回
我尝试的内容:我找到了实现count的解决方案,并检查它是否等于outter map函数。它也不起作用,因为要么我的代码发送得太快(在迭代完成之前),要么根本无法解析
我将非常感谢听到任何建议,甚至实践(我应该这样做还是不这样做),因为我正在努力解决这个问题将近2天
这是它大致的样子(原始版本更复杂):
以下是代码的链接:
如果您可以使用async/await模式,那么您可以按照以下方式更改问题中的代码。这将允许您迭代播放器,一旦您的函数完成,您就可以对更改的播放器数据进行处理 注意,因为它们是引用,所以它们在原始数组中会发生更改,如果您不想这样做,可以深入克隆数组,并在那里进行更改 请注意,这里提出的代码是基于异步/等待模式的,并展示了一种抽象的方式来更改它
const mockedData=[
{玩家:1,值:1000},
{玩家:2,值:1500},
{玩家:3,值:1900}
];
const mockedPlayers=[
{玩家:1,值:1000},
{玩家:2,值:1500},
{玩家:3,值:1900}
];
异步函数findArrayInDb(matchBy,sortBy){
//您可以在这里创建数据库调用
//并将参数用于属性筛选
//现在,总是一样的
返回新承诺((解决、拒绝)=>{
setTimeout(()=>resolve(mockedData),1000);
});
}
const dodelayedpromisework=异步(玩家)=>{
for(设i=0;i{
log(“迭代模拟玩家”);
var结果=等待doDelayedPromisesWork(模拟玩家);
返回新承诺(resolve=>resolve());
};
doPlayerMagic()。然后(()=>/*完成了播放器的迭代*/console.log('finished');
//在球员发生任何事情之前跑
console.log(“指令发送”)代码>函数map
不是异步的,您可以完成所有工作并返回已解析的承诺(promise.resolve
)检查更新您的解析,因为我看到它在players.map函数中。另外,map返回一个新数组,如果你想检查每个玩家,那么foreach应该做得很好,就我个人而言,我不觉得给定的代码非常容易阅读(你想知道地图在哪里),而且这个计数是绝对不必要的,因为解析只有一个位置,在players.map函数后面。你在哪里定义玩家?这不是示例代码的一部分。我甚至不认为有必要在这里承诺你的代码工作良好,尽管有许多风格上的问题。你在这里使用承诺的原因是什么?您是否正在尝试将循环卸载到另一个线程中?你不能这样做。小提琴读起来很长,而且在执行时不会做任何事情。是的,他们会的,尽管我必须说,你的“地图”在那里是完全无用的,这只是一种使用for循环的奇特方式,它不会返回任何东西。我在您的JSFIDLE中看到的一种非常抽象的代码编写方法如下
[
{
id: 1,
val: 400
}
{
id: 2,
val: 590
}
]
const do_magic_with_measurements = (db, data) => {
let session = data.session;
let player = data.player;
let count = 0;
return new Promise((resolve, reject) => {
session.Measurements.map(measurement => {
player.Stats.map(stat => {
if (measurement.Type === stat.Type) {
/* Update maximum value */
if (measurement.MaxValue === stat.MaxValue) {
db.collection(SESSIONS_COLLECTION)
.find({
PlayerID: ObjectID(session.PlayerID),
"Measurements.Type": measurement.Type
}, {
"Measurements.$": 1
})
.sort({
"Measurements.MaxValue": -1
})
.toArray()
.then(one_session => {
console.log(one_session);
if (one_session[0].Measurements[0].MaxValue == stat.MaxValue) {
// update maximum value if they were equal
stat.MaxValue = 0;
} else {
// otherwise set the next maximum value
stat.MaxValue = one_session[0].Measurements[0].MaxValue;
}
})
.catch(error => {
throw error;
.catch(error => {
throw error;
});
}
}
});
});
count++;
if (count === session.Measurements.length) {
resolve(player);
}
});
};