2016-05-27 2 views
0

рассмотреть этот кодnodejs - передать глобальные переменный пообещать обратный вызов в синтаксических

for (var i = 0; i < data.length; i++){ 
    query.equalTo("objectId",data[i].id).first().then(
     function(object){ 
      object.set("username", data[i].username); 
      object.save(); 
     } 
    ); 
} 

в этом примере data[i] внутри then callback последний элемент массива

рассмотреть этот 2-й примера, который обычно работает в JavaScript мир

предположим, что мы используем некоторые API, которые соединяют с MongoDB и имеет функцию под названием обновление

for (var i = 0; i < data.length; i++){ 
    query.eq("_id",data[i].id).update(data[i].username); 
} 

eq возвращает объект, update обновляет этот объект и сохраняет его.

то не будет удивительным, если что-то подобное можно ... (не уверен, что он также будет работать даже)

for (var i = 0; i < data.length; i++){ 
    query.equalTo("objectId",data[i].id).first().then(
     function(object, data[i]){ 
      object.set("username", data.username); 
      object.save(); 
     } 
    ); 
} 

ответ

3

Это на самом деле не работает только из обзорного var. Вы можете получить образец работает как хотелось бы просто:

а) с использованием let вместо var

б) создание новой области для i (это то, что let в основном делает). (В анонимной Fn, я использовал ii вместо i только для ясности i также будет работать.):

for (var i = 0; i < data.length; i++){ 
    (function(ii) { 
     query.equalTo("objectId",data[ii].id).first().then(
      function(object){ 
       object.set("username", data[ii].username); 
       object.save(); 
      } 
     ); 
    })(i) 
} 
+0

В JavaScript все переменные, объявленные с помощью var, являются областями действия. Вы получаете эту проблему, потому что данные линии [i] .username выполняются асинхронно, и это время i относится к последнему (или некоторому другому) индексу данных. Чтобы преодолеть этот сценарий, мы используем Closure, как объясняется @Tomas –

+0

@JitendraKhatri @Tomas Я думаю, что это не сработает, потому что в синтаксическом анализе мы не можем передать переменную в 'then callback' ... Tomas использовал второй пример, который был предложен как решение (thenken) (функция (токен, data [i] {...} ', но parse использует' then (function (token) {...} ' – Eltorrooo

+0

Да, я вижу проблему - я просто редактировал вторую фрагмент кода, который вы указали, - что неверно. Я отредактирую ответ –

0

лучший способ решить эту проблему с parse является использование рекурсии

... 

    var do = function(entries, i){ 
     if (entries[i]){ 

      let user = data[i]; 

      query.equalTo("objectId", user.id).first().then(
       function(object){ 
        object.set("username", user.username); 
        object.save(); 
       } 
      ).then(
       function(){ 
        return do(entries, i + 1); 
       } 
      ); 
     } 
    } 
Смежные вопросы