Node.js node-async.map如何工作?

Node.js node-async.map如何工作?,node.js,async.js,Node.js,Async.js,在阅读了async之后,我假设下面的代码将向控制台输出http/API调用返回的所有值的总和;但它似乎在第一个http调用返回后立即启动,并且只显示一个与API返回的第一个值相等的“total”值 我对async.map工作原理的误解在哪里 var http = require('https'); const async = require('async'); var MongoClient = require('mongodb').MongoClient; var dbUrl = "mong

在阅读了
async
之后,我假设下面的代码将向控制台输出http/API调用返回的所有值的总和;但它似乎在第一个http调用返回后立即启动,并且只显示一个与API返回的第一个值相等的“total”值

我对async.map工作原理的误解在哪里

var http = require('https');
const
async = require('async');

var MongoClient = require('mongodb').MongoClient;
var dbUrl = "mongodb://localhost:27017/";

var total = 0;

var tokens = [ {
    name : "tron"
}, {
    name : 'cardano'
}, {
    name : 'nucleus-vision'
}, {
    name : 'ripple'
}, {
    name : 'litecoin'
}, {
    name : 'havven'
}];

function run() {

    doStuff();
    setInterval(doStuff, 1 * 60 * 1000);
};

function doStuff() {

    total = 0;

    async.map(tokens, httpGet, function (value){
          console.log('async done ', total);
        });

}

function httpGet(token, callback) {

    var url = 'https://api.coinmarketcap.com/v1/ticker/' + token.name;
    http.get( url,
        function(res) {
            var body = '';

            res.on('data', function(chunk) {
                body += chunk;
            });

            res.on('end', function() {
                var jsonObj = JSON.parse(body);
                var price = parseFloat(jsonObj[0].price);

                total += price;

                MongoClient.connect(dbUrl, function(err, db) {
                    if (err)
                        throw err;
                    var dbo = db.db("crypto");
                    dbo.collection("tick").insertOne(jsonObj[0],
                            function(err, res) {
                                if (err)
                                    throw err;
                                db.close();

                            });
                });


                callback(price);
            });



        }).on('error', function(e) {
        console.log("Got an error: ", e);
    });

};


run();

传递给迭代对象(
httpGet
)的
回调
使用不正确。第一个参数(
price
)被视为错误。发件人:

如果
iteratee
将错误传递给其回调函数,则会立即调用main
回调函数(对于map函数)

所以

宁可

callback(null, price);

因此
async
在第一次迭代后不会停止。

传递给迭代对象(
httpGet
)的回调
使用不正确。第一个参数(
price
)被视为错误。发件人:

如果
iteratee
将错误传递给其回调函数,则会立即调用main
回调函数(对于map函数)

所以

宁可

callback(null, price);

因此
async
在第一次迭代后不会停止。

我认为这里有两个独立的问题:

  • 您可能知道,我们不能像在同步代码中那样在异步代码中使用
    return
    语句,这就是为什么我们使用回调。节点样式的回调在
    函数(err,result){}
    的形式上,其中第一个参数是错误(如果有),第二个参数是函数的结果(返回值)。据报道,,
    Async.map(coll、iteratee、callback)
    将在
    iteratee
    将错误传递给其回调

    当您的
    iteratee
    -函数调用其回调时:
    callback(price)
    ,您实际上停止了执行,因为price作为
    error
    参数传递。要“返回”
    price
    变量,您要做的是这样调用回调:
    callback(null,price)

  • 通常,-函数用于

    将给定函数应用于列表的每个元素,以相同的顺序返回结果列表

    异步库的map函数也执行相同的操作,即:迭代数组并返回结果项的数组,就像normalmap(下面)方法一样

    [1,2,3].map(函数(nbr){return nbr*2})//返回[2,4,6]

    回调的结果参数(即async.map的第三个参数)将使用价格数组调用,而不是价格的总和

    async.map(令牌、httpGet、函数(错误、总数){
    console.log(错误);//打印未定义(除非有错误)
    console.log(总计);//打印价格数组
    });


  • 对于求和值,我建议使用函数,或者简单地求和结果返回的值。

    我认为这里有两个不同的问题:

  • 您可能知道,我们不能像在同步代码中那样在异步代码中使用
    return
    语句,这就是为什么我们使用回调。节点样式的回调在
    函数(err,result){}
    的形式上,其中第一个参数是错误(如果有),第二个参数是函数的结果(返回值)。据报道,,
    Async.map(coll、iteratee、callback)
    将在
    iteratee
    将错误传递给其回调

    当您的
    iteratee
    -函数调用其回调时:
    callback(price)
    ,您实际上停止了执行,因为price作为
    error
    参数传递。要“返回”
    price
    变量,您要做的是这样调用回调:
    callback(null,price)

  • 通常,-函数用于

    将给定函数应用于列表的每个元素,以相同的顺序返回结果列表

    异步库的map函数也执行相同的操作,即:迭代数组并返回结果项的数组,就像normalmap(下面)方法一样

    [1,2,3].map(函数(nbr){return nbr*2})//返回[2,4,6]

    回调的结果参数(即async.map的第三个参数)将使用价格数组调用,而不是价格的总和

    async.map(令牌、httpGet、函数(错误、总数){
    console.log(错误);//打印未定义(除非有错误)
    console.log(总计);//打印价格数组
    });

  • 对于求和值,我建议使用函数,或者简单地求和结果返回的值