【已解决】Nodejs中调用async.map如何传递获得的结果?

【已解决】Nodejs中调用async.map如何传递获得的结果?

众所周知,map可以把一个数组中的项每个变量遍历一遍,执行同一个异步操作,然后将结果存到最后的回调函数中。 例如: async.map([‘file1’,‘file2’,‘file3’], fs.stat, function(err, results){ // results就是最终返回的数据 }); 但是我现在遇到这样一个问题,我得到了一个数组,但是数组里面的数据有些是我错误的,所以我调用了一个方法getExistAdLocPage。在方法getExistAdLocPage中,我使用了map来对数组中的每一项进行分析(例如:数组中的数据是url,我用request来分析是否真的存在这些url,判断他们是不是404),然后给数组中的数据添加了一个状态,若是存在,stat=true, 否则就stat=false. 代码如下:

var getExistAdLocPage = function(data, callback){
	async.map(data,function(item,callback) {
		var name = item['name'];
		var result = item['url'];
		if(result.indexOf("502 Bad Gateway") > -1) {
			callback(null,{"stat":"webfail","name":name});
		} else if(result.indexOf("404-1") > -1) {
			callback(null,{"stat":"page not exist","name":name});
		} else if(result.indexOf("404 Not Found") > - 1) {
			callback(null,{"stat":"page not exist","name":name});
		} else if(result.indexOf("<!DOCTYPE") > - 1){
			callback(null,{"stat":"page not exist","name":name});
		} else if(result.indexOf("403 Forbidden") > - 1){
			callback(null,{"stat":"page not exist","name":name});
		} else {
			callback(null,{"stat":"success","name":name,"data":result});
		}
	},function(err,result) {
		console.log(result);		
	});
}

我的问题是如何把result中的数据传给我的调用函数。是在async.map外面包一层callback吗?怎么包?谢谢大家


3 回复

【已解决】Nodejs中调用async.map如何传递获得的结果?

在Node.js中,async.map 是一个非常有用的工具,用于将一个数组中的每个元素进行异步处理,并将结果收集到一个新的数组中。你提到的问题是关于如何正确地将 async.map 的结果传递给外部调用函数。

示例代码

假设你有一个包含 URL 的数组,你想检查每个 URL 是否存在(即是否返回 404 错误)。你可以使用 async.map 来实现这一目标,并将结果传递给外部调用函数。

const async = require('async');
const request = require('request');

var getExistAdLocPage = function(data, callback) {
    async.map(data, function(item, innerCallback) {
        const url = item['url'];
        
        request(url, (err, res, body) => {
            if (err) {
                return innerCallback(err);
            }

            if (res.statusCode === 404) {
                innerCallback(null, { stat: 'page not exist', name: item['name'] });
            } else {
                innerCallback(null, { stat: 'success', name: item['name'], data: body });
            }
        });
    }, function(err, results) {
        if (err) {
            return callback(err);
        }

        // 将结果传递给外部调用函数
        callback(null, results);
    });
};

// 调用示例
const urls = [
    { name: 'URL1', url: 'http://example.com/page1' },
    { name: 'URL2', url: 'http://example.com/page2' },
    { name: 'URL3', url: 'http://example.com/page3' }
];

getExistAdLocPage(urls, (err, results) => {
    if (err) {
        console.error('Error:', err);
    } else {
        console.log('Results:', results);
    }
});

解释

  1. 定义 getExistAdLocPage 函数:

    • 这个函数接受两个参数:data(包含 URL 的数组)和 callback(用于传递结果的回调函数)。
  2. 使用 async.map:

    • async.map 遍历 data 数组中的每个元素,并对每个元素执行异步操作(在这里是请求 URL)。
    • 对于每个 URL,我们使用 request 模块来发起 HTTP 请求。
    • 如果请求成功且状态码不是 404,则将结果标记为 “success”;否则,标记为 “page not exist”。
  3. 处理结果:

    • async.map 的回调函数接收两个参数:errresults
    • 如果有错误发生,直接通过 callback 返回错误。
    • 如果没有错误,将 results 传递给外部调用函数的 callback

这样,你就可以通过 callbackasync.map 的结果传递给外部调用函数。


已解决,这个问题其实是对异步调用不熟悉导致的。在异步调用中,要明白数据是不能向同步中那样传来传去的,每个数据的传递操作都是callback来callback回去,这边只要把最后一行的console.log(result)改成callback(err,result)即可。当然要记得调用getExistAdLocPage的时候记得写callback函数,如 getExistAdLocPage([{data:“1”,name:“abc”}],function(err,data){ console.log(data); });

在你的getExistAdLocPage函数中,你需要确保最终的结果能够通过callback传递出去。你可以通过在async.map的外部包裹一层callback来实现这一点。

以下是修改后的代码示例:

var async = require('async');
var request = require('request'); // 假设你已经在项目中引入了request库

var getExistAdLocPage = function(data, callback) {
    async.map(data, function(item, innerCallback) {
        var name = item['name'];
        var url = item['url'];
        
        request(url, function(error, response, body) {
            if (error || response.statusCode >= 400) {
                return innerCallback(null, {"stat": "page not exist", "name": name});
            }
            
            innerCallback(null, {"stat": "success", "name": name, "data": body});
        });
    }, function(err, results) {
        callback(err, results);
    });
};

// 使用示例
var data = [
    {name: 'item1', url: 'http://example.com/page1'},
    {name: 'item2', url: 'http://example.com/page2'}
];

getExistAdLocPage(data, function(err, result) {
    console.log(result);
});

在这个示例中,async.map内部的innerCallback用于处理每次请求的结果,并将其传递给外部的callback。最终的results会在所有异步请求完成后被传递回调用getExistAdLocPage的地方。这样,你就可以正确地获取到所有的结果并进行后续处理了。

回到顶部