简体   繁体   English

如何在 nodejs 中执行此异步功能

[英]How can I do this asyn feature in nodejs

I have a code to do some calculation.我有一个代码来做一些计算。 How can I write this code in an asyn way?如何以异步方式编写此代码? When query the database, seems we can not get the results synchronously.查询数据库时,似乎无法同步获取结果。 So how to implement this kind of feature?那么如何实现这种功能呢?

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;
}

Its not possible to return the result of an asynchronous function, it will just return in its own function scope.不可能返回异步函数的结果,它只会在自己的函数范围内返回。

Also this is not possible, the result will always be unchanged (null)这也是不可能的,结果将始终保持不变(空)

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

Put a callback in the calc() function as second parameter and call that function in the client.query callback with the result在 calc() 函数中放置一个回调作为第二个参数,并在 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);
   });
}

Now if you want the main to return that result, you also have to put a callback parameter in the main and call that function like before.现在,如果您希望 main 返回该结果,您还必须在 main 中放置一个回调参数并像以前一样调用该函数。

I advice you to check out async its a great library to not have to deal with this kind of hassle我建议您查看async它是一个很棒的库,而不必处理这种麻烦

Here is a very crude way of implementing a loop to perform a calculation (emulating an asynchronous database call) by using events.这是通过使用事件来实现循环以执行计算(模拟异步数据库调用)的一种非常粗略的方法。

As Brmm alluded, once you go async you have to go async all the way.正如 Brmm 所暗示的,一旦你采用异步方式,你就必须一直采用异步方式。 The code below is just a sample for you to get an idea of what the process in theory should look like.下面的代码只是一个示例,让您了解理论上的过程应该是什么样子。 There are several libraries that make handling the sync process for asynch calls much cleaner that you would want to look into as well:有几个库可以让您更清晰地处理异步调用的同步过程:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM