在forEach循环中更改JSON值

时间:2019-04-11 19:41:29

标签: javascript node.js json es6-promise

我正在为服务器设置API,并且尝试更新由国家/地区代码和数字值组成的JSON中的值。 我遍历了从我的数据库(MongoDB)中检索到的JSON数组并更新了值,然后在完成循环后,我尝试返回更新后的列表。

问题在于返回值是原始列表,没有更新。 我已经验证了更新是在循环内进行的。

我对JS还是很陌生,所以我尝试在letconst之间切换,尝试直接更新countryList(但是当我阅读一些帖子时,我了解到js按值而不是按引用传递所有参数。

//shortened list, just for the example. The original has all country codes.
const countryList = JSON.parse('{"ZW": 0, "ZM": 0, "ZA": 0, "YT": 0, "YE": 0, "WS": 0, "WF": 0}'); 
let updateCountryList = () => {
    let temp = countryList;
    db.collection('tweets').find({'place': {$ne: null}}).forEach((item) =>{
        if (item.emoji_list.includes(emoji)) {
            temp[item["place"]["country_code"]] += 1;
            console.log(temp); //prints updated list
        }
    });
    console.log(temp); //prints original, empty list
    return temp
};

鉴于上面的JSON,预期的输出应类似于: {"ZW": 5, "ZM": 896, "ZA": 466, "YT": 23, "YE": 0, "WS": 1, "WF": 0}

我应该提到,这是承诺和更长过程的一部分。但是,这是第一件事。

编辑: 这是解决问题的方法:

const countryList = JSON.parse('{"ZW": 0, "ZM": 0, "ZA": 0, "YT": 0);
let updateCountryList = () => {
    return new Promise(resolve1 => {
        let temp = countryList;
        db.collection('tweets').find({'place': {$ne: null}}).forEach((item) => {
            if (item.emoji_list.includes(emoji)) {
                temp[item["place"]["country_code"]] += 1;
            }
        }).then(() => {
            resolve1(temp)
        });

    });

};
updateCountryList().then(temp => {
    console.log(temp); // WORKS :)
});

2 个答案:

答案 0 :(得分:2)

因为要在另一个函数中进行更新,并且JS是异步的,所以您可能在真正更新之前返回了未更改的数据。

您可以传递回调:

const updateCountryList = (cb) => {
  db.collection('tweets').find({'place': {$ne: null}}).forEach((item) => {
    let temp = countryList
    if (item.emoji_list.includes(emoji)) {
      temp[item["place"]["country_code"]] += 1
    }
    cb(temp)
  })
}

或者,如果您的Mongo客户端使用Promises,则可以使用async / await或在最终的.then中返回更新的列表

答案 1 :(得分:0)

我相信您应该使用“最终尝试”方法,通过完成所有更改来使json更新。

类似的东西:

try {    
    const countryList = JSON.parse('{"ZW": 0, "ZM": 0, "ZA": 0, "YT": 0, "YE": 0, "WS": 0, "WF": 0}'); 
    db.collection('tweets').find({'place': {$ne: null}}).forEach((item) =>{
        if (item.emoji_list.includes(emoji)) {
            temp[item["place"]["country_code"]] += 1;
            console.log(temp); //prints updated list
        }
    });
} finally {
    console.log('FINALLY ', temp);
    return temp;
}