2012-11-30 29 views
3

我有一段代碼來進行一些計算。 如何以異步方式編寫此代碼? 查詢數據庫時,似乎無法同步獲得結果。 那麼如何實現這種功能呢?如何在nodejs中執行此異步功能

function main() { 
    var v = 0, k; 
    for (k in obj) 
     v += calc(obj[k].formula) 
    return v; 
} 

function calc (formula) { 
    var result = 0; 
    if (formula.type === 'SQL') { 
     var someSql = "select value from x = y"; // this SQL related to the formula; 
     client.query(someSql, function (err, rows) { 
      console.log(rows[0].value); 
      // *How can I get the value here?* 
     }); 
     result = ? // *How can I return this value to the main function?* 
    } 
    else 
     result = formulaCalc(formula); // some other asyn code 
    return result; 
} 

回答

3

它不可能返回異步函數的結果,它只會返回它自己的函數範圍。

而且這是不可能的,結果永遠是不變的(空)

client.query(someSql, function (err, rows) { 
    result = rows[0].value; 
}); 
return result; 

放入鈣()函數,第二個參數的回調,並調用該函數與該client.query回調導致

function main() { 
    calc(formula,function(rows) { 
     console.log(rows) // this is the result 
    }); 
} 

function calc(formula,callback) { 
    client.query(query,function(err,rows) { 
     callback(rows); 
    }); 
} 

現在如果你想主要以返回結果,你也必須把回調參數在主裏面並調用它像以前一樣。

我建議你檢查出async它的一個偉大的圖書館不具備處理這種麻煩

0

這裏是實現一個循環來進行計算(模擬異步數據庫調用)的一種非常原始的方式通過使用事件。由於Brmm暗示,一旦你走異步,你必須一路走向異步。下面的代碼只是一個示例,讓您瞭解理論上的過程應該是什麼樣子。有幾個庫可以處理異步呼叫的同步過程,並且您還希望查看以下內容:

var events = require('events'); 
var eventEmitter = new events.EventEmitter(); 
var total = 0; 
var count = 0; 
var keys = []; 

// Loop through the items 
calculatePrice = function(keys) { 
    for (var i = 0; i < keys.length; i++) { 
     key = keys[i]; 
     eventEmitter.emit('getPriceFromDb', {key: key, count: keys.length}); 
    }; 
} 

// Get the price for a single item (from a DB or whatever) 
getPriceFromDb = function(data) { 
    console.log('fetching price for item: ' + data.key); 
    // mimic an async db call 
    setTimeout(function() { 
     price = data.key * 10; 
     eventEmitter.emit('aggregatePrice', {key: data.key, price: price, count: data.count}); 
    }, 500); 
} 

// Agregate the price and figures out if we are done 
aggregatePrice = function(data) { 

    count++; 
    total += data.price; 
    console.log('price $' + price + ' total so far $' + total); 

    var areWeDone = (count == data.count); 
    if (areWeDone) { 
     eventEmitter.emit('done', {key: data.key, total: total}); 
    } 
} 

// We are done. 
displayTotal = function(data) { 
    console.log('total $ ' + data.total); 
} 

// Wire up the events 
eventEmitter.on('getPriceFromDb', getPriceFromDb); 
eventEmitter.on('aggregatePrice', aggregatePrice); 
eventEmitter.on('done', displayTotal); 

// Kick of the calculate process over an array of keys 
keys = [1, 2, 3] 
calculatePrice(keys);