Nodejs async.map复杂情况处理?请教大家

Nodejs async.map复杂情况处理?请教大家

现在有一个需求,有一个二位数组[[a,b,c],[e,f,g],[h,i,j],[k,l,m]],另外有一个数N,求出结果 [[a-N,b-N,c-N],[e-N,f-N,g-N],[h-N,i-N,j-N],[k-N,l-N,m-N]], 请问用async.map怎么实现? 上面可能不涉及回掉函数,实际场景是这样 有一个中心点center,有一组天已经分好天[[a,b,c],[e,f,g],[h,i,j],[k,l,m]],有一个path的数据库保存着点到中心点之间的交通信息。现在需要遍历数组, 查询出数据库的信息,组合成新的带有交通信息的数组输出出来。


6 回复

当然可以!async.mapasync 库中的一个方法,用于并行处理数组中的每个元素,并将结果收集到一个新的数组中。在你的场景中,你需要遍历二维数组,并针对每个子数组查询数据库以获取交通信息,然后将这些信息组合成新的数组。

下面是具体的实现步骤:

  1. 安装 async: 如果你还没有安装 async 库,可以通过 npm 安装:

    npm install async
    
  2. 实现逻辑: 下面是一个示例代码,展示了如何使用 async.map 来实现你的需求。

const async = require('async');

// 模拟数据库查询函数
function getTrafficInfo(point, callback) {
    // 这里假设 point 是一个包含 x 和 y 坐标的对象
    const trafficInfo = {
        distance: Math.sqrt((point.x - center.x) ** 2 + (point.y - center.y) ** 2),
        time: Math.random() * 10  // 随机生成时间
    };
    setTimeout(() => {
        callback(null, trafficInfo);
    }, 100); // 模拟异步操作
}

// 中心点坐标
const center = { x: 0, y: 0 };

// 输入数据
const points = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]];

// 处理函数
function processPoint(point, callback) {
    const [x, y, z] = point;
    const pointObj = { x, y, z };
    
    async.parallel([
        (cb) => getTrafficInfo({ x, y }, cb),
        (cb) => getTrafficInfo({ x, z }, cb),
        (cb) => getTrafficInfo({ y, z }, cb)
    ], (err, results) => {
        if (err) return callback(err);
        
        // 组合结果
        const result = {
            originalPoint: point,
            trafficInfo: results
        };
        
        callback(null, result);
    });
}

// 使用 async.map 处理所有点
async.map(points, processPoint, (err, results) => {
    if (err) throw err;
    
    console.log(results);
});

解释

  1. getTrafficInfo:模拟从数据库查询交通信息的函数。这里我们假设返回的是距离和时间。
  2. processPoint:处理每个点的函数。它首先将点转换为对象形式,然后使用 async.parallel 并行查询多个交通信息(例如点与点之间的距离)。
  3. async.map:遍历输入的二维数组 points,并使用 processPoint 函数处理每个点。最终的结果是一个包含原始点及其交通信息的新数组。

这样,你就可以通过 async.mapasync.parallel 实现复杂的异步处理逻辑了。


用数组的map就行了,和aysnc无关

我搞过一个类似的,写得像屎一样…… auto有几个步骤,最后一步对一个结果进行each遍历。在遍历过程中又有几个步骤,最后一步又对一个结果进行each遍历。忘了还有没有第三个嵌套循环。 重点是有些步骤有提前结束所有任务(不是出错哦),比如说查了数据库,发觉 user 是天灾的成员,好了,后面的不用做了,不得不用 callback(‘break’, result) 这样丑陋的方法解决。 更蛋疼的是,如果查了数据库,user 是天灾的话执行一种逻辑,是近卫的执行一种逻辑……额,我崩溃了…… 求大神怎么破

先把二位数组变成一维,再用aysnc.map遍历不就行了

var list= [0, 1, 2];
var howdo = require('hodwo');

howdo.each(list, function(index, val, done){
     // do sth
	 // done 提交结果,可以放在异步回调里
	 done(err, ret);
}).together(function(err, ret0, ret1, ret2){
     // together 为顺序并行,结果和 list 顺序一样
	 // do sth
});

针对你提到的需求,我们可以使用 async 库中的 map 方法来处理复杂的异步操作。假设你已经有了一个函数 getTrafficInfo 来获取每个点到中心点之间的交通信息。我们可以通过以下步骤实现:

  1. 使用 async.map 遍历二维数组。
  2. 在遍历过程中,调用 getTrafficInfo 函数获取交通信息。
  3. 将交通信息与原数据组合后返回。

下面是一个示例代码:

const async = require('async');

// 假设这是获取交通信息的函数
function getTrafficInfo(point, callback) {
    // 模拟异步操作,例如数据库查询
    setTimeout(() => {
        const trafficInfo = { /* 交通信息 */ };
        callback(null, trafficInfo);
    }, 500);
}

const points = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [10, 11, 12]
];

const center = [0, 0, 0]; // 中心点坐标

async.map(points, (point, callback) => {
    // 获取交通信息
    getTrafficInfo(point, (err, trafficInfo) => {
        if (err) return callback(err);
        
        // 处理交通信息并返回新的点数组
        const newPoint = point.map((value, index) => value - center[index] + trafficInfo[index]);
        callback(null, newPoint);
    });
}, (err, results) => {
    if (err) throw err;
    console.log(results); // 输出结果
});

在这个例子中:

  • getTrafficInfo 是一个模拟的异步函数,用于获取每个点的交通信息。
  • async.map 遍历 points 数组,对每个点调用 getTrafficInfo 函数。
  • 在获取到交通信息后,将交通信息与原数据组合,并通过回调函数返回新的点数组。
  • 最终结果会在回调函数中输出。

这种方法可以有效地处理复杂的异步操作,并且保持代码结构清晰。

回到顶部