Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > JavaScript, Ajax
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.05.2016, 15:27   #1
Gekan
Пользователь
 
Регистрация: 29.06.2012
Сообщений: 39
По умолчанию Асинхронная функция

Всем привет.
Есть такой пример:
Код:
<script>
var count = 0;
var f = function(){
    count++;
    if (count==10) {
        return;
    }
    document.write("1");
    setTimeout(f, 1000);
};

document.write("0");
f();
document.write("2");
</script>
И этот код выдаёт 01211111111 (там конечно стирается из-за document.write, но не суть).
А как сделать так, чтобы код выдавал 01111111112, т.е. приостановить что ли эту асинхронность? Т.е. нужен аналог sleep() в Java.
В данном примере можо было бы так:
Код:
<script>
var count = 0;
var f = function(){
    count++;
    if (count==10) {
        document.write("2");
        return;
    }
    document.write("1");
    setTimeout(f, 1000);
};

document.write("0");
f();
</script>
Но хотелось бы увидеть какое-то универсальное решение, если такое есть.
Может как-то использовать Deferred из JQuery?
Gekan вне форума Ответить с цитированием
Старый 16.05.2016, 15:37   #2
come-on
Участник клуба
 
Регистрация: 21.10.2015
Сообщений: 1,361
По умолчанию

setTimeout и есть слип, если вам не нужна в принципе асинхронность то зачем тут ее мучать?
вообще вы бы рассказали что надо
come-on вне форума Ответить с цитированием
Старый 16.05.2016, 15:49   #3
Gekan
Пользователь
 
Регистрация: 29.06.2012
Сообщений: 39
По умолчанию

Например, есть вызов 3 функций:
Код:
document.write("0");
f();
document.write("2");
Они вызываются в одном потоке (ну в javascript по-другому вроде не бывает) одна за другой.
В функции f() у меня идёт в цикле какое-то действие, например вывод цифры 1, но необходимо каждую цифру выводить через 1 секунду. Ну и пока не закончено выполнение f() следующие инструкции не должны выполняться, в данном пример имею в виду строку:
Код:
document.write("2");
Gekan вне форума Ответить с цитированием
Старый 16.05.2016, 22:42   #4
Fenex
Форумчанин
 
Аватар для Fenex
 
Регистрация: 15.02.2012
Сообщений: 821
По умолчанию

Тут два выхода
1) вызывать последующие функции из коллбека:
Код:
function before() {
  console.log("Start");
}

function action() {
  if (count == 5) {
    after();
    return;
  }
  console.log(count++);
  setTimeout(action, 1000);
}

function after() {
  console.log("End");
}

var count = 0;
before();
action();
2) использовать промисы:
Код:
var action = function(count) {
  var defer = jQuery.Deferred();
  var isLast = true;

  while (count--) {
    (function(count, isLast) {
      setTimeout(function() {
        console.log(count);
        if (isLast) defer.resolve();
      }, count * 1000);
    })(count, isLast);

    isLast = false;
  }

  return defer.promise();
};

console.log("Start");
action(5).then(function() {
  console.log("End");
});
^-.-^ My GitHub

Последний раз редактировалось Fenex; 17.05.2016 в 06:21.
Fenex вне форума Ответить с цитированием
Старый 18.05.2016, 17:02   #5
Gekan
Пользователь
 
Регистрация: 29.06.2012
Сообщений: 39
По умолчанию

Спасибо за пример с Deferred.
А как быть, если эту функцию action вызывать в цикле?
То есть вот так если написать, то не работает так как ожидается.
Код:
for  (var k = 0; k < 3; k++ ){
    console.log("Start");
    action(15).then(function() {
        console.log("End");
    });
}
Gekan вне форума Ответить с цитированием
Старый 18.05.2016, 19:18   #6
Fenex
Форумчанин
 
Аватар для Fenex
 
Регистрация: 15.02.2012
Сообщений: 821
По умолчанию

Что-то вроде этого должно быть.
Код:
var chain = jQuery.when();
for(var k=0; k<3; k++) {
    chain = chain
    .then(function() {
        console.log("Start");
    }).then(function() {
        return action(5);
    }).then(function() {
        console.log("End");
    });
}
^-.-^ My GitHub

Последний раз редактировалось Fenex; 18.05.2016 в 19:26.
Fenex вне форума Ответить с цитированием
Старый 19.05.2016, 10:47   #7
Naive
Раздолбайских Дел
Старожил
 
Аватар для Naive
 
Регистрация: 22.05.2009
Сообщений: 3,828
По умолчанию

Цитата:
Сообщение от Fenex Посмотреть сообщение
Что-то вроде этого должно быть.
Код:
var chain = jQuery.when();
for(var k=0; k<3; k++) {
    chain = chain
    .then(function() {
        console.log("Start");
    }).then(function() {
        return action(5);
    }).then(function() {
        console.log("End");
    });
}
не-а, надо замыкание запилить
Alar, верни репу!
Naive вне форума Ответить с цитированием
Старый 19.05.2016, 21:03   #8
Fenex
Форумчанин
 
Аватар для Fenex
 
Регистрация: 15.02.2012
Сообщений: 821
По умолчанию

с чего это вдруг?
^-.-^ My GitHub
Fenex вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Функция объявленная на сервере как асинхронная генерируется на клиенте как синхронная (C# WCF) NewLamer&Programer Общие вопросы .NET 2 22.04.2016 19:28
Асинхронная загрузка скрипта alexfuryk JavaScript, Ajax 0 22.02.2013 14:17
Асинхронная загрузка скриптов ekvador JavaScript, Ajax 0 27.01.2012 15:12
Асинхронная загрузка Julitan JavaScript, Ajax 2 18.08.2011 16:32
Асинхронная передача данных eda Microsoft Office Excel 4 17.08.2009 14:16