node.js - 请教关于node异步循环的问题
迷茫
迷茫 2017-04-17 11:21:38
0
2
672

代码很简单,如下:

var find;
data.some(function(ip) {
    client.sismember(url+':ip', ip, function(err, mem) {
        !mem && (find = ip);
        console.log('redis:' + find);
    });

    console.log(find);
    return find;
});

原理很简单:

  • 我先some循环一个IP数组
  • 如果数组中的IP不存在redis中,我就将find赋值为当前IP
  • 如果循环过程中找到了IP,我就跳出循环,不再一直查询redis

结果,代码中有两个console:

  • 先循环数组数据,find一直是undefined,因此不会跳出循环
  • 之后执行所有redis查询结果,并重复给find复制,并打印出来

问题:

  • 首先结果不是我想要的
  • 效率差,我循环100条就查询100次redis

请问如何解决?

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(2)
伊谢尔伦
  1. 安装万能的async:sudo npm install async
  2. 把代码改成:
var async = require('async');

...

async.detect(
  data, 
  function(ip, cb) {
    client.sismember(url+':ip', ip, function(err, mem) {
        console.log('redis:' + find);
        cb(!mem);
    });
  },
  function(result) {
    find = result;
    console.log(find);
});

可以看下github上async的文档。

小葫芦

用q.js的解决方案

npm i q

var Q = require('q');
function find (data, url, timeout) {
    var deferred = Q.defer();
    var n = data.length;
    data.forEach(function (ip) {
        Q.ninvoke(client, 'sismember', url + ':ip', ip)
            .then(function (ret) {
                if(ret) {
                    deferred.resolve(ip);
                } else if (--n <= 0) {
                    deferred.reject(new Error('Not found!'));
                }
            });
    });
    return Q.timeout(defered.promise, timeout);
}
//以上只用写一次,以下是使用方法
find(data, url, 1000)
    .then(function (ip) {
        //成功找到
        console.log('redis:' + find);
    }).fail(function (reason) {
        //没找到或超时
    });
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板