Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Свой Promise (https://javascript.ru/forum/project/70113-svojj-promise.html)

Nexus 11.08.2017 11:53

Свой Promise
 
Да, велосипед.
Promise описываемый в учебнике мне не понравился.
jQ.deferred не реализовывал желаемого (а может просто руки кривые). Хотелось, чтобы обработчик вызывался, даже если Promise.state!=pending.

function Promise(){
	var state='pending',
		done=[],
		fail=[],
		always=[],
		context,
		_arguments=[],
		execute=function(list){
			var containers=[list,always],
				args=[];

			for(var container in containers){
				if(!containers.hasOwnProperty(container))
					continue;

				container=containers[container];
				for(var i in container){
					if(!container.hasOwnProperty(i))
						continue;

					container[i].apply(context||window,_arguments);
					delete container[i];
				}
			}
		};

	this.set_arguments=function(_args){
		_arguments=[];
		for(var i=0;i<_args.length;i++)
			_arguments.push(_args[i]);

		return this;
	};

	this.resolve=function(){
		state='resolved';
		this.set_arguments(arguments);
		execute(done);

		return this;
	};
	this.reject=function(){
		state='rejected';
		this.set_arguments(arguments);
		execute(fail);

		return this;
	};
	this.done=function(){
		done.push(arguments[0]);
		if(state=='resolved')
			this.resolve.apply(this,_arguments);

		return this;
	};
	this.fail=function(){
		fail.push(arguments[0]);
		if(state=='rejected')
			this.reject.apply(this,_arguments);

		return this;
	};
	this.always=function(){
		always.push(arguments[0]);
		if(state!='pending')
			this[state=='resolved'?'resolve':'reject']();

		return this;
	};
	this.set_context=function(cont){
		context=cont;

		return this;
	};

	function Instance(self){
		var __context=self;

		this.done=function(callback){
			__context.done.call(__context,callback);

			return this;
		};
		this.fail=function(callback){
			__context.fail.call(__context,callback);

			return this;
		};
		this.always=function(callback){
			__context.always.call(__context,callback);

			return this;
		};
		this.set_context=function(context){
			__context.set_context.call(__context,context);

			return this;
		};

		return this;
	};
	this.promise=function(){
		return new Instance(this);
	};

	return this;
}

Alexandroppolus 11.08.2017 15:47

Цитата:

Сообщение от Nexus
Promise описываемый в учебнике мне не понравился.

что с ним не так? :) Он, конечно, не умеет set_context и set_arguments, зато может много чего невероятно крутого.

Nexus 14.08.2017 12:56

Alexandroppolus, мне не понравилось, что вся асинхронность должна происходить в теле функции, которая передается конструктору класса.

Alexandroppolus 14.08.2017 14:03

Nexus,

ты можешь "вывернуть промис наизнанку":
var obj = {};
obj.promise = new Promise(function(resolve, reject) {
  obj.resolve = resolve;
  obj.reject = reject;
});


теперь в объекте obj у тебя есть оба метода окончания асинхронности (с ними можно что-то делать), и созданный промис, который можно куда-то передать, например.

Nexus 14.08.2017 14:17

Alexandroppolus, согласен, можно было написать "обертку" для нативного промиса, но свой велосипед уже написан)


Часовой пояс GMT +3, время: 16:44.