Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从具有异步调用的for循环返回_Javascript_Node.js - Fatal编程技术网

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

Javascript 从具有异步调用的for循环返回,javascript,node.js,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.le

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

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是异步的,所以两个返回都会被调用,所以如何停止执行并在找到匹配项后立即返回


谢谢

停止执行由hgetall函数负责,所以您可以使用最简单的简单解决方案-传递给它数组函数,该函数调用您的本地let赋值函数。找到匹配项或发生错误后,只需将本地函数替换为空即可。现代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));

您的逻辑并不是完全错误的,您有一个回调作为参数,所以当结果出现时,代码将正确运行。但是,根本不需要返回,这并不会触发必须在返回后执行的代码的执行。之后要做的所有事情都必须在回调中,而不是按顺序放在validate调用之后。一个简单的解决方案是将redis.hgetall调用封装在一个函数中,该函数将把i作为附加参数,并将回调存储为变量。像这样,i的值将是正确的。有些东西会在我的大脑中敲响警钟。。当未找到任何内容且未发生错误时,如何调用回调?也许我错了,但这段代码不是依赖于同步执行吗?如果第一个实例比第二个实例需要更多的时间来回答问题并抛出错误,那么第二个实例的cbc函数是否仍然存在?@Kaddath您是对的,这只是建议用例的代码概念。当然,原始cbc函数应该监视调用的第n个计数,并在最后一次迭代中执行错误的分支回调。关于异步执行,很可能这不是问题,因为每个闭包都有自己的实例。同样,它主要回答了“如何从异步回调返回”的问题,所以实现了不可控函数的停止调用回调。