2013-02-14 3 views
0

поэтому я должен вычислить share в цикле. На каждой итерации этого цикла я должен получить переменную с именем rent из массива. Поэтому я разделил функцию calculate на базу данных.Функции и обратные вызовы в Node.js

var calculate = function() { 
    while(count < 100) { 
     var share = 50; 
     var shareArray = []; 

     for(var i = 0; i < 100; i++) { 

      var pension = share*2; // mathematical stuff 
      // Gets a rent from a database and returns it in a callback 
      getRent(modules, share, function(rent) { 
       share = rent*foo; // some fancy mathematical stuff going on here 
       // I need to get the share variable above out of its function scope 
      }); 
        // I need the share variable right here 
      shareArray.push(share);  // the value of share will be for i = 0: 50, i= 1: 50 ... 
             // This is not what i want, i need the share value from getRent() 
     } 
     count++; 
    } 
} 

Теперь, как вы можете видеть, мне представлены следующие проблемы. Поскольку я работаю в node.js, единственный способ получить переменную rent из массива модулей - через эту функцию обратного вызова, которая называется getRent(). Дело в том, что мне нужно значение share после этого шага, но вне getRent(). Есть ли способ, которым я могу это сделать?

Это getRent() - Функция:

var getRent = function(modules, share, callback) { 
     // Searching for a fitting rent in the modules array 
     // Just assume this is happening here 
     callback(rent); 
}; 

Итак, вопрос: как я могу "вернуться" share:

getRent(modules, share, function(rent) { 
        share = rent*foo; // some fancy mathematical stuff going on here 
        // I need to get the share variable above out of its function scope 
}); 

каким-либо образом?

+0

Что означает «getFromDB()»? Я не понимаю, как это может работать, поскольку выборка из базы данных почти наверняка включает асинхронный шаг. – Pointy

+0

Кроме того, вы почти наверняка будете намного лучше, с точки зрения производительности, если бы вы могли сделать ** один ** запрос, чтобы получить все нужные вам значения, а не отдельный запрос для каждого из них. Это будет намного, намного медленнее, чтобы сделать это по одному. – Pointy

+0

Прошу прощения. Это просто построенный пример. Настоящий код будет трудно объяснить это. Просто предположим, что это работает. Mhh maybee, я отредактирую его. –

ответ

0

Вы хотите использовать whilst метод async библиотеки (npm install async), чтобы упростить это:

var count = 0; 
var shareArray = []; 

async.whilst(
    function() { 
     return count < 100; 
    }, 
    function (next) { 
     count++; 
     getRent(function(rent) { 
      // What does modules do anyway?? 
      // Dont know where foo comes from... 
      shareArray.push(rent*foo); // some fancy mathematical stuff going on here 
      next(); 
     }); 
    }, 
    function (err) { 
     console.log(shareArray); 
     // Do sth. with shareArray 
    } 
); 

Если бы это было хорошо для вас, чтобы просить все 100 вызова параллельно, можно также использовать функцию parallel ,

1

Если getRent is async, то нет возможности получить результат синхронно. По сути, вы не знаете значения, которое getRent в конечном итоге обеспечит его обратный вызов, пока он, наконец, не вернет его. Поэтому речь идет не о сфере функций, а о сроках. Вам просто нужно подождать getRent, чтобы сделать это, прежде чем вы сможете получить значение для rent. Вам необходимо реорганизовать свой код, чтобы calculate также был асинхронным.

Что-то вроде:

// Refactor calculate to be async: 
function calculate(cb) { 
    var data = []; 
    for (var i=0; i<100; i++) { 
     getRent(function (rent) { 
      data.push(rent); 
      if (data.length === 100) cb(data); 
     }); 
    } 
} 

// And then use it async: 
calculate(function (data) { 
    // data array arrives here with 100 elements 
}); 

выше ответ, возможно, подобно тому, как вы можете достичь его с ванильным JS. Использование библиотеки async, например, предложений miggs, вероятно, является хорошей идеей в долгосрочной перспективе. Но, как я уже сказал, если вы используете vanilla JS или async lib, вам не придется уклоняться от факта, что вам придется рефакторировать асинхронность как в этом коде, так и в коде, который его вызывает.

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