2014-02-06 6 views
1

В качестве новичков js/node у меня возникают проблемы с пониманием того, как я могу обойти эту проблему.Область обратного вызова NodeJS

В основном у меня есть список объектов, которые я хотел бы сохранить в базе данных MongoDB, если они еще не существуют.

Вот код:

var getDataHandler = function (err, resp, body) { 
    var data = JSON.parse(body); 
    for (var i=0; i < data.length; i++) { 
     var item = data[i]; 
     models.Entry.findOne({id: item.id}, function(err, res) { 
      if (err) { } 
      else if (result === null) { 
       var entry = new models.Entry(item); 
       feedbackEntry.save(function(err, result) { 
        if (err) {} 
       }); 
      } 
     }); 
    } 
} 

У меня есть проблема в том, что, поскольку он является асинхронным, когда new models.Entry(item) линии выполнена значение элемента будет равно последним элемент в массиве данных для каждого один обратный вызов.

Какую модель можно использовать, чтобы избежать этой проблемы?

Спасибо.

ответ

2

Два вида моделей доступны:

1) Callbacks. То есть вы продолжаете вызывать функции из своих функций, передавая их в качестве параметров. Обратные вызовы обычно прекрасны, но, особенно, серверная сторона при работе с базой данных или другими асинхронными ресурсами, вы быстро заканчиваете «обратный ад», и вы можете устать от поиска трюков, чтобы уменьшить уровни отступов вашего кода. И вы можете иногда удивляться, как вы действительно дело с исключениями. Но обратные вызовы являются основой: вы должны понять, как справиться с этой проблемой, используя обратные вызовы.

2)Promises. Использование обещаний, которые вы можете иметь что-то подобное (пример из моей related blog post):

db.on(userId)   // get a connection from the pool 
.then(db.getUser)  // use it to issue an asynchronous query 
.then(function(user){ // then, with the result of the query 
    ui.showUser(user); // do something 
}).finally(db.off); // and return the connection to the pool 

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


Что касается вашей проблемы области видимости с переменным Развивающимся до обратного вызова вызываются, стандартное решение это один:

for (var i=0; i<n; i++) { 
    (function(i){ 
     // any function defined here (a callback) will use the value of i fixed when iterating 
    })(i); 
}); 

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

+0

Спасибо! Вы упомянули обратные вызовы - я передаю функции в качестве аргументов в настоящее время, но как я могу использовать шаблон обратного вызова таким образом, пока обеспечение переменной элемента не всегда является последним элементом в списке? Кроме того, с обещаниями будет ссылаться на текущий пункт или на значение предмета, когда обещание возвращается? – Sherlock

+0

Я отредактировал пункт «переменная элемента не всегда является последним элементом в списке». –

+0

Отлично, спасибо вам за помощь! – Sherlock

Смежные вопросы