从具有异步调用的for循环返回

时间:2017-07-21 10:19:01

标签: javascript node.js

我有这个函数被调用一次:

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对象,并将一些字段与一些字段进行比较以提供新数据。如果有匹配,我想用false回调并返回。如果没有匹配,我想返回true。

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

由于

1 个答案:

答案 0 :(得分:1)

停止执行是hgetall函数的责任,因此您可以使用最简单的直接解决方案 - 传递给它的数组函数,该函数调用本地的let-assigned函数。找到匹配后(或发生错误),只需将local函数替换为空。现代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));