vinilzen
@vinilzen

Из-за чего проблема с последовательностью событий в js?

Доброе время суток,
буду благодарен за совет или хотя бы пните в какую сторону смотреть.

Имеется долго играющий рендер элементов на Backbone, код ниже
или тут пример с проблемой на jsbin
var MyView = Backbone.View.extend({
	tagName:'p',
	className:'List',
	page:1,
	render: function(widget_collection) {
		while ( this.page < 15 ) {
			this.createPage();
			this.addToLogNumberPage(this.page);
			this.page++;
		}
		return this;
	},
	addToLogNumberPage:function(page){
		console.log('add:'+page);
		$('.log').append('Page N'+page+'printed, ');
	},
	createPage:function(){
		var i = 0;
		while (i<100000000){ i++; }
		this.$el.append('<span>'+this.page+'</span>')
	}
})

var my_view = new MyView();

$('button').click(function(){
	$('.progressBar').show();
	$('.log').show();
	$('body').append(my_view.render().el);
})


Не могу понять, почему .progressBar и .log отображается после рендера всех элементов, хотя console.log('add:'+page); печатается по ходу выполнения...
DOM как будто зависает, отображает все только после отработки render()
  • Вопрос задан
  • 3033 просмотра
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Вы стали свидетелем одной из оптимизаций современных браузеров.

http://jsbin.com/OBaMoqe/1 - в комментариях пометил основную суть, но повторюсь

когда вам нужно выполнить что-то жирное, вы непременно должны вынести это дело из общего контекста выполнения (через setTimeout или предпочтительнее webworkers), иначе остальной код и все события по перерисовке будут ожидать окончания работы этой жирной логики.

js - асинхронный язык. Вся соль языка в том, что все тяжелые вычисления можно и нужно проводить паралельно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
miraage
@miraage
Старый прогер
Не уверен, но, быть может действительно манипуляции с DOM выполнятся по завершению всей функции click(). Если это так, то поведение очень странное.
Ответ написан
А время отработки метода show() сколько у Вас стоит по умолчанию?

Скорее всего у Вас progressBar не успевает появиться - его анимацию перекрывают вычисления. DOM не обновляется пока не закончатся вычисления.

Решается это просто: либо показываем progressBar сразу без анимации, либо задерживаем вычисления на время анимации.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы