2016-03-04 2 views
3

Я нашел поведение, которое вызывает у меня проблемы с JavaScript. У меня есть две функции:продолжить цикл for после выполнения функции JavaScript

var show_uploaded = function(data_photo), который получает информацию о загруженных фотографий в качестве параметра,

function exif_like(path){/*working with my image*/ console.log('exif_like END'); }
, которая получает путь к каждому одной загруженной фотографии в качестве параметра.

Я сделал такой код:

var show_uploaded = function(data_photo){ 
    for(var z = 0; z < data_photo.length; z++){ 
     var send_image_name = uploaded_photo[z].name; 
     $.ajax({ 
      data: { compare : send_image_name }, 
      url: 'get_panorama.php', 
      method: 'POST', // or GET 
      success: function(path){ 
       exif_like(path); 
       console.log('FOR LOOP END'); 
      } 
     }); 
    } 
}; 

Но что я вижу в консоли является то, что «FOR LOOP END» Журнал отображается перед тем журнал «exif_like END». И это вызывает некоторое непредсказуемое поведение в моем коде.

Есть ли какое-либо решение, как продолжить цикл после выполнения функции exif_like()?

+0

Ну, вы получите несколько журналов «для конца цикла», так как они находятся внутри цикла 'for'. Вы уверены, что не видите одного из них перед другим «exif end» - они все равно должны появляться попарно? –

+0

Можем ли мы увидеть больше содержимого 'exif_like'? Вы используете внутри нее методы async? –

+0

Например, когда я загружаю 3 фотографии, konsole печатает: «FOR LOOP END», «FOR LOOP END», «FOR LOOP END», «exif_like END», «exif_like END», «exif_like END» .. и они должны по-прежнему появляются в парах: «exif_like END», «FOR LOOP END», «exif_like END», «FOR LOOP END», «exif_like END», «FOR LOOP END» –

ответ

1

Если вы пытаетесь иметь exif_like() делать вещи между Ajax звонками, просто ваш exif_like() вызова функции следующего запросом Ajax, когда он заканчивается.

Использование тестовых данных из json placeholder, что-то, как это будет работать:

JavaScript

uploaded_photo = [{name: 1},{name: 2},{name: 6},{name: 8},{name: 9},{name: 11},{name: -1}] 
pointer = 0; 

function exif_like(path){ 
    /*working with my image*/ 
    obj = JSON.parse(path) 
    if(obj.length > 0) { 
    console.log('\t\tdata returned:'+obj[0].id + ' '+obj[0].title) 
     console.log('exif_like END for '+obj[0].id); 
    } else { 
    console.log('\t\tNo data returned') 
     console.log('exif_like END'); 
    } 

    /* Code here can be executed before the next Ajax call */ 
    console.log('Do stuff before the next ajax call...') 

    pointer++; 
    if(pointer < uploaded_photo.length) { 
    show_uploaded(); 
    } 
} 

var show_uploaded = function(){ 
    console.log('---Start of Ajax call---'); 

    $.ajax({ 
    data: { id : uploaded_photo[pointer].name }, 
    url: 'https://jsonplaceholder.typicode.com/posts', 
    method: 'GET', 
    complete: function(xhr){ 
     console.log('---End of Ajax call---'); 
     exif_like(xhr.responseText); 
    } 
    }); 
}; 

show_uploaded() 

Выход

--- Начало Ajax вызова ---
--- Конец звонка Аякса ---
возвращаемые данные: 1 Сюнт Aut Facere repellat предусмотрительный occaecati excepturi Optio reprehenderit
exif_like КОНЦА для 1
делать вещи до следующего вызова Ajax ...
--- Начало Ajax вызова ---
--- Конец Ajax вызова ---
возвращаемые данные: 2 дш Эст еззе
exif_like кОНЦА для 2
ли вещи до следующего вызова Ajax ...
--- Начало Ajax вызова ---
- -End звонка Ajax ---
данные возвращены: 6 dolorem eum magni eos aperiam quia
exif_like END для 6
Сделайте материал перед следующим вызовом ajax ...
--- Начало Ajax вызова ---
--- Конец Ajax вызова ---
возвращаемые данные: 8 dolorem Dolore Эст ipsam
exif_like КОНЦА для 8
ли вещи до следующего вызова Ajax. ..
--- Начало Ajax вызова ---
--- Конец Ajax вызова ---
возвращаемые данные: 9 nesciunt Omnis dolorem юре Темпора и др accusantium
exif_like END для 9
ли вещество перед следующий вызов ajax ...
--- St искусство Ajax вызова ---
--- Конец Ajax вызова ---
возвращаемые данные: 11 и др еа Веро Quia laudantium autem
exif_like END для 11
ли вещи до следующего вызова Ajax ...
--- Начало Ajax вызова ---
--- Конец Ajax вызова ---
нет данных возвращается
exif_like END

JS Скрипки Пример: https://jsfiddle.net/igor_9000/wwj11udx/3/

Надеюсь, что это поможет!

* Редактировать: Обновлен код для использования функции complete, а в случае, если есть запросы, которые не преуспевают.

+0

точно, это хорошая идея, спасибо! –

2

Если остаток процессов возврата ожидаемых результатов, и exif_like фактически выполняет только console.log() вы можете попробовать использовать $.when()

$.when(exif_like(path)).then(function() {console.log("FOR LOOP END")}) 
+0

И если моя функция возвращает true в конце, после упомянутого console.log() можно сделать что-то вроде этого: $ .when (exif_like (path) == true) .then (function() {console.log ("FOR LOOP END")})? –

+0

@ PetrBečka Да, должно быть возможно сделать что-то подобное. хотя это ваш вопрос, описанный в OP, и комментарий http://stackoverflow.com/questions/35801224/continue-in-for-loop-after-function-is-done-javascript/35801434?noredirect=1#comment59272406_35801224? Также обратите внимание: ни одно значение не возвращается из 'exif_like (path)' at 'js' at Question? – guest271314

+0

Спасибо, я попробую. Да, это мой вопрос. –

1

Заменить for loop в while цикла, состояние до data_photo не пусто, то перед Отправной while цикл не создавать flag переменная, которая будет логическим идентификатором, который обработчик ajax success завершен, и следующий ajax может быть отправлен. Смотрите ниже код с комментируемыми изменениями:

var show_uploaded = function(data_photo){ 
    // Create flag 
    var flag = true; 
    var length = data_photo; 

    // continue loop execution until data_photo not empty 
    while (length){ 
    if(flag){ 
     var send_image_name = uploaded_photo[--length].name; 
     // Set flag to false, until success executed 
     flag = false; 
     $.ajax({ 
      data: { compare : send_image_name }, 
      url: 'get_panorama.php', 
      method: 'POST', // or GET 
      success: function(path){ 
       exif_like(path); 
       console.log('FOR LOOP END'); 
       // We are ready to perform next ajax, set flag to true. 
       flag = true; 
      }, 
      error: function(path){ 
       // Error or not we have to set flag to true to allow further iterating 
       flag = true; 
      } 
     }); 
    } 
} 
}; 
+0

@HurricaneHamilton Я добавил комментарии к коду и ссылку на описание цикла while в js –

+0

Спасибо для обновления кода. Похоже, что это запустит цикл while, отправит первый запрос ajax, а затем пропустит остальные элементы, потому что нет способа, которым me.flag присваивается значение true до окончания цикла while. Помните, что успешные и обратные вызовы ошибок являются асинхронными. –

+0

Да, вы правы, также новый аякс не будет отправлен, а data_photo не будет выталкиваться за 1 элемент до тех пор, пока флаг не станет истинным, что означает, что предыдущий ajax должен быть в onSuccess или on onError. –

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