node.js - 请教关于node异步循环的问题
迷茫
迷茫 2017-04-17 11:21:38
[Node.js讨论组]

代码很简单,如下:

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) {
        //没找到或超时
    });
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号