2017-07-21 54 views
0

我有获取调用此函数一次:从返回的for循环它有一个异步调用

exports.validate = function(roomData, callback) { 
    console.log('This only prints only once!'); 

    getAllRooms(function(rooms) { 
    if (rooms.length === 0) { 
     callback(true); 
     return; 
    } 

    for (let i = 0; i < rooms.length; i++) { 
     let key = "roomAdmin:" + rooms[i].roomName; 

     redis.hgetall(key, function() { 
     let newUrl = roomData.url.toLowerCase(); 
     let existingUrl = rooms[i].url.toLowerCase(); 
     let newRoomName = roomData.roomName.toLowerCase(); 
     let existingRoomName = rooms[i].roomName.toLowerCase(); 

     if (newUrl === existingUrl || newRoomName === existingRoomName) { 
      console.log('This prints'); 
      callback(false); 
      return; 
     } 
     if (i === rooms.length - 1) { 
      console.log('But this prints also?'); 
      callback(true); 
      return; 
     } 
     }) 
    } 
    }); 
}; 

我通过一组Redis的对象试图循环和比较一些领域一些给新数据。如果有一场比赛,我想用虚假的回报进行回叫。如果没有匹配,我想返回true。

我可以看到我的逻辑在下面是错误的,因为hgetall是异步的,因此两个返回都会被调用,所以如何在我找到匹配时立即停止执行并返回?

感谢

+0

你的逻辑并不完全错误,你有一个回调的参数,所以当结果那里的代码将正常继续。但是,根本不需要返回,这不是触发执行后面必须执行的代码的事情。所有这些都必须在回调中完成,而不是在'validate'调用之后顺序放置。一个简单的解决方案是将'redis.hgetall'调用包装在一个函数中,该函数将附加参数'i'和'callback'作为var存储。像这样,'i'的值将是正确的 – Kaddath

回答

1

停止执行是以hgetall功能的责任,所以你可以用最简单直接的解决方案 - 传递给它的阵列功能,这就要求当地让分配的功能。找到匹配后(或发生错误),只需将本地函数替换为空。现代ES解释器优化器将足够快地执行代码,但不会执行额外的回调。

喜欢的东西如下:

let cbc = function() { 
    let newUrl = roomData.url.toLowerCase(); 
    let existingUrl = rooms[i].url.toLowerCase(); 
    let newRoomName = roomData.roomName.toLowerCase(); 
    let existingRoomName = rooms[i].roomName.toLowerCase(); 
    // ...... 
    if(found) { 
     cbc =() => {}; 
     callback(result); 
     return 
    } 
}  
// ...... 
redis.hgetall(key, (...args) => cbc(...args)); 
+0

在我的大脑中,有一些东西让钟声响起。当没有发现任何错误并且没有错误发生时,如何调用回调函数?也许我错了,但是这个代码不依赖类似于同步的执行吗?如果第一个实例比第二个实例需要更多时间来回答(并抛出错误),那么第二个实例中是否仍然存在“cbc”函数? – Kaddath

+0

@Kaddath你说得对,它只是建议用例的代码概念。当然,原来的'cbc'函数应该监视第n个调用次数,并且在最后一次迭代中执行假分支回调。关于异步执行,很可能,这不是问题,因为每个闭包都有它自己的实例。再次 - 它主要回答问题'如何从异步回调返回',因此实现停止调用不可控制函数的回调。 –