2016-12-16 3 views
1

Я пытаюсь создать событие, управляемое while, в javascript. По сути, он выполняет итерацию через массив значений и делает запрос во время каждой итерации. Затем, основываясь на результатах запроса, он должен либо продолжать цикл, либо останавливаться и что-то делать.Обратный вызов Javascript в цикле while не работает?

Я понимаю, что вы не можете иметь обратные вызовы в цикле while, поэтому я смущен тем, как даже реализовать такую ​​вещь. Вложенные функции повторяются, и это не идеально.

мой код цикла:

   var done = false; 
      while(!done){ 
       bridgeCheckRooms(send,function(reply){ //callback 
        console.log(tagArray[count]); 
        console.log(reply); 
        if(reply.success){ 
         done = true; 
        } else { 
         count--; 
        } 
       }); 
      } 
+3

Вы должны называть себя снова, когда вы «не сделали», вместо того, чтобы иметь петлю –

+1

другими словами, вы должны смотреть в рекурсии –

+2

делает bridgeCheckRooms сделать асинхронный вызов? – Learning2Code

ответ

2

Вы должны использовать рекурсию. Подход к этому будет примерно таким:

 function next() { 

      // .... 

      bridgeCheckRooms(send,function(reply){ //callback 
       console.log(tagArray[count]); 
       console.log(reply); 
       if(reply.success){ 
        // continue() ? 
        // done = true; 
       } else { 
        count--; 
        next(); 
       } 
      }); 
    } 

    next(); 

Конечно, это только пример. Вы должны адаптировать его ко всему вашему коду.

+0

Я был делая то же самое раньше, но когда он наконец заканчивается, функция все еще называется. Я завершаю log 'done', когда он входит в блок успеха, но' done' регистрируется более одного раза. Я предполагаю, что функция все еще называется даже после ее завершения. –

+0

Единственная причина, по которой будет вызываться функция, - это если 'reply.success' является ложным - единственный способ, которым вы будете продолжать регистрироваться, - это если обратный вызов' bridgeCheckRooms' вызывается несколько раз «bridgeCheckRooms» - объясните немного о 'bridgeCheckRooms' и о том, как функция обратного вызова используется этой функцией –

+0

, функция моста излучает сообщение сокета с запрашиваемой комнатой. после того, как номер был найден или найден пустым, сервер отправляет ответ, который затем отправляется обратно в исходную функцию. вот код для моста: 'function bridgeCheckRooms (send, callback) { socket.emit ('room-check', send); // когда номер был получен socket.on ('номер проверено' + send.id, функция (ответ) { обратного вызова (ответ); }); } 'не слишком уверен, правильно ли он будет отформатировать –

0

Я думаю, вы хотите изучить отложенные объекты и обещания. Вы хотите подождать, пока не будет выполнен асинхронный вызов, чтобы проверить, нужно ли продолжать цикл.

Или вы можете сделать это синхронным звонком, если здесь нет асинхронного использования.

+2

Это было бы лучше в качестве комментария, если вы не добавите код для резервного копирования вашего утверждения о том, что обещания будут полезны –

+2

в браузерах, синхронные сетевые запросы устарели на основной поток, так что если это код браузера (и нет никаких указаний, что это НЕ), это плохое предложение –

0

Ваш код будет правильным, если bridgeCheckRooms был синхронным и заблокировал поток выполнения до тех пор, пока ответ не был возвращен. Смотрите эту SO post on synchronicity

Вот то, что происходит в вашем коде:

Блок кода в цикле в то время как выполняется bridgeCheckRooms, который мы будем предполагать, делает какую-то работу, то в очереди на асинхронный вызов к базе данных. bridgeCheckRooms затем вернется, и выполнение вашего цикла while будет немедленно продолжено, а очередь еще раз вызовет bridgeCheckRooms.

Их ключевая часть заключается в том, что bridgeCheckRooms является асинхронной функцией и не блокирует выполнение до его завершения. Поэтому, когда вы вызываете bridgeCheckRooms, он просто ставит асинхронный вызов в очередь, но не ждет, пока он не завершится.

Итак, если ваш цикл while выполняется 10 раз, вы получите 10 в ожидании запросов к базе данных. Но эти запросы не будут выполняться до тех пор, пока цикл while не завершит выполнение и не выполнит выполнение для асинхронной очереди.

@pablo имеет для этого правильный подход кода. Разница между его кодом и вашим кодом заключается в том, что второй асинхронный вызов не выполняется до завершения первого асинхронного вызова.

Edit: CallbackHell.com выглядит как большой учебник по этой теме

Смежные вопросы