mongoose findone область обратного вызова (NodeJS, экспресс) - PullRequest
0 голосов
/ 24 февраля 2012

Я пытаюсь очистить данные из внешнего канала JSON и сохранить их в моем mongoDB.

request(url, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var jsonObj = JSON.parse(body);
        // console.log(jsonObj.events[1].id) <-- this works
        for (var i = 0; i < jsonObj.events.length; i++) { 
            // add jsonObj.events[i] as a new record to table
            // console.log(jsonObj.events[i].id) <-- this works
            Wnet.findOne({ id : jsonObj.events[i].id }, function (err, doc){
                if (err || doc == null) {
                     // console.log(jsonObj.events[i].id) <-- this doesn't work!
                     // record is new, add it
                }
            });
         }
     }
});

Обратите внимание на операторы console.log ... последний (внутри обратного вызова .findOne) не работает.

Я все еще изучаю все тонкости JavaScript, но я считаю, что это проблема области действия ... функция обратного вызова не знает jsonObj. Но я не знаю, как передать это в функцию.

Делая шаг назад, я пытаюсь проверить коллекцию на наличие записи. Если он не может найти его, я хочу добавить запись из извлеченного массива JSON. Если есть лучший способ сделать это, я буду рад вашей помощи в его поиске.

1 Ответ

2 голосов
/ 24 февраля 2012

Это не проблема области.С точки зрения объема, он будет искать переменную, поднимаясь вверх.Так что в findOne есть переменная jsonObj.Он будет подниматься до var jsonObj = ... выше.

Я полагаю, ваша проблема в том, что вы проходите через jsonObj.events и запускаете findOne для каждого.Затем вы пытаетесь утешить jsonObj.events[i].id в обратном вызове findOne для каждого.Проблема в том, что ваш i увеличивается каждый раз.И действительно закончится, когда i >= jsonObj.events.length.Таким образом, если длина равна 9, тогда i в конечном итоге станет 10, когда цикл завершится.Таким образом, ваша регистрация не будет работать. РЕДАКТИРОВАТЬ: Чтобы уточнить, регистрация не будет работать, потому что в цикле все findOne сработает, но обратные вызовы не произойдет сразу.Потому что обратные вызовы асинхронны.Таким образом, к тому времени, когда произойдут обратные вызовы, цикл, вероятно, завершится, и он попытается записать events, который не существует.

Попробуйте это:

request(url, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var jsonObj = JSON.parse(body);
        //console.log(jsonObj.events[1].id) <-- this works
        for (var i = 0; i < jsonObj.events.length; i++) { 
            // add jsonObj.events[i] as a new record to table
            //console.log(jsonObj.events[i].id) <-- this works
            Wnet.findOne({ id : jsonObj.events[i].id }, function (err, doc){
                if (err || doc == null) {
                    console.log(jsonObj.events[this].id);
                    //record is new, add it
                }
            }.bind(i));
         }
     }
});

Это всего лишь одинспособ справиться с этим.Если bind сбивает с толку, попробуйте другой способ.Вы также можете сделать что-то вроде:

    request(url, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var jsonObj = JSON.parse(body);
        //console.log(jsonObj.events[1].id) <-- this works
        for (var i = 0; i < jsonObj.events.length; i++) { 
            // add jsonObj.events[i] as a new record to table
            //console.log(jsonObj.events[i].id) <-- this works
            doFindOne(jsonObj.events, i);
         }
     }
});


function doFindOne(events, i) {
    Wnet.findOne({ id : events[i].id }, function (err, doc){
        if (err || doc == null) {
            console.log(events[i].id);
            //record is new, add it
        }
    });
}

Во втором примере мы вызываем функцию, которая будет удерживать i в рамках этого вызова.Это может иметь больше смысла.(переплет имеет тенденцию запутывать больше, чем уточнять)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...