Показать сообщение отдельно
  #1 (permalink)  
Старый 19.03.2014, 17:21
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Асинхронный вызов функций
Посоветуйте, какой из вариантов реализации setImmediate выбрать для асинхронного вызова функций?

Первый вариант:
var callAsync = function () {

	var fakeNode = document.createElement("img"), storage = {}, uid = 0;
	fakeNode.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
	fakeNode.style.cssText = "position: absolute; top: -9999px; left: -9999px; width: 0; height: 0;";
	document.body.appendChild(fakeNode);
	fakeNode.addEventListener("load", function (event) {
		var key = event.key, data = storage[key];
		data.callback.call(data.thisObj, data.data);
		delete storage[key];
	});

	return function (callback, thisObj, data) {
		var key = "call" + uid++;
		storage[key] = {
			data: data,
			thisObj: thisObj,
			callback: callback
		};
		var event = document.createEvent("HTMLEvents");
		event.initEvent("load", false, false);
		event.key = key;
		fakeNode.dispatchEvent(event);
	};

}();

callAsync(function () {
	throw Error("test");
});
alert("done");
В этом варианте, мне не нравится, что лишний <img> будет все время находится на странице, попадать в коллекции или мешать какому-нибудь nth-child. А если кому-нибудь вздумается скрипт в <head> засунуть, то придется еще и DOMContentLoaded добавлять для всего, что будет использовать callAsync.


Второй вариант:
var message = "ServiceMessage", storage = {}, uid = 0;

addEventListener("message", function (event) {
	var key = event.data, data;
	if (typeof key == "string" && key.indexOf(message) == 0) {
		data = storage[key];
		data.callback.call(data.thisObj, data.data);
		delete storage[key];
	}
});

function callAsync(callback, thisObj, data) {
	var key = message + uid++;
	storage[key] = {
		data: data,
		thisObj: thisObj,
		callback: callback

	};
	postMessage(key, "*");
}

callAsync(function () {
	throw Error("test");
});
alert("done");
В этом варианте боюсь, что постоянный флуд в message кому-нибудь навредит.



Третий вариант с использованием setTimeout не рассматриваю, так как не устраивает скорость выполнения.

Последний раз редактировалось Octane, 23.03.2014 в 14:59.
Ответить с цитированием