Изменить значение JSON в цикле forEach - PullRequest
1 голос
/ 11 апреля 2019

Я устанавливаю API для своего сервера и пытаюсь обновить значение в JSON, состоящее из кодов стран и числовых значений.Я перебираю массив JSON, извлеченный из моей БД (MongoDB), и обновляю значение, затем после завершения цикла я пытаюсь вернуть обновленный список.

Проблема в том, что возвращаемое значение является исходным списком, без обновлений.Я проверил, что обновление происходит внутри цикла.

Я новичок в JS, поэтому я пробовал переключаться между let и const, пытался обновить 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 ]

2 голосов
/ 11 апреля 2019

Поскольку вы обновляете внутри другой функции, а 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

0 голосов
/ 11 апреля 2019

Полагаю, вам следует использовать метод try finally, чтобы обновить свой 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...