3

Всем привет, работаю с jQuery, нужна помощь.
Нужно вызывать функцию, каждый раз разное кол-во раз.
Функция проводит вычисления и заносит в базу данных.
Одно срабатывание функции занимает от 30 секунд.
Как вызывать функцию, что бы второй вызов не начинался пока первый не закончится?
Думал через цикл while сделать, но он не ждет пока функция выполнится, и вызывает ее еще раз. Сделать false функцию не могу, т.к тогда браузер зависнет окончательно.

while (CountTr != 0) {
                var ds = 0 // номер tr из которой вытаскиваю ссылку для функции
                var game_table = main_table.children('tr').eq(ds).children('td:first').children('a').attr('href');
                var time = main_table.children('tr').eq(ds).children('td').eq(1).children('span').html();
                analitics (game_table, time); // сама функция которую нужно вызвать несколько раз
                CountTr = CountTr - 1; 
                $('#schet').html(CountTr); // отображение на какой итерации цикл
            }
Black_Dog
  • 153
  • http://js-help.net/text/function/recursivnie_function/recursivnie_function.php – perfect Sep 27 '16 at 06:46
  • 1
    Посмотрите мой ответ. Там не совсем ваш случай - но вопрос как дождаться окончания выполнения асинхронной функции там рассматривается. – Pavel Mayorov Sep 27 '16 at 09:31

4 Answers4

1

Если ваша функция работает долго и не является асинхронной, то ваш код должен работать верно (просто процесс будет "зависать" на время выполнении функции). Однако если у вас асинхронное выполнения (например ajax вызовы), то решение простое - это промисы (читать тут). Т.к. только механизм "обещаний" может четко определить что функция завершила свою работу (или нет) для передачи управления дальше по коду.

alexoander
  • 1,640
  • 14
  • 20
  • сейчас учу промисы, если все получится, отмечу ответ правильным – Black_Dog Sep 28 '16 at 06:04
  • Да я собственно не за отметкой бегу =) Мне важно, чтобы это помогло вам. К тому же там есть комментарий от Pavel Mayorov - там тоже полезный материал для изучения. Лучше всего если вы сможете разобраться с вопросом и ответить на него сами тут (заодно и я изучу мб что-то и мне не знакомо) =) – alexoander Sep 28 '16 at 06:30
0

Лучше всего перенести вызов новой итерации внутрь функции в коллбеке асинхронной части. В таком случае следующая итерация гарантировано будет после предыдущей.

var CountTr = n; // количество итераций
var ds = 0 // номер tr из которой вытаскиваю ссылку для функции
var game_table = main_table.children('tr').eq(ds).children('td:first').children('a').attr('href');
var time = main_table.children('tr').eq(ds).children('td').eq(1).children('span').html();

analitics(game_table, time, CountTr); //передаем CountTr в функцию

function analitics(game_table, time, CountTr) {
  $('#schet').html(CountTr); // отображение на какой итерации цикл

  // асинхронное тело функции

  analitics(game_table, time, --CountTr); // рекурсивно вызываем функцию с меньшим значением CountTr
}
-1

На самом деле эту задачку могут спросить на собеседованиях. Советую вам подробнее разобраться в этом вопросе. Для решения вам могут помочь Promise и Named Functions. Идея может выглядеть как то так:

// worker function
function rand() {
    return Promise.resolve(Math.random())
}

// main function
function runner(fun, times) {
    if (!times) { return }

    return fun().then( x => {
        console.log(x)
        runner(fun, times - 1)
    })
}

// async function call!
runner(rand, 3) /*.then() */

Но здесь не решена проблема с this и аргументами.

-1

как вариант

var work = false;

var interval = setInterval(function () {
if (work != true){
    work = true
    async(function () {
        work = false
    })
}
}, 1000)

function async(callback) {
    // тут что то делаем 30 секунд
    callback()
}
xFloooo
  • 1,101