@bioforge
Верстающий пыхер

Как можно организовать работу с асинхронным кодом?

Добрый день!
Есть код
var paramPamPam = {

    data : null,

    get : function () {
        var _this = this;

        return $.post('/path/to/file', function(data, textStatus, xhr) {
            _this.data = data;
        }); 
    },


    _enable: function () {
        console.log('enable');
    },
    enable: function () {

        var _this = this;
        
        if ( this.data ) {
            _this._enable();
        } else {
            this.get().done(function () {
                _this._enable();
            });
        };

    },


    _disable: function () {
        console.log('disable'); 
    },
    disable: function () {
        var _this = this;
        
        if ( this.data ) {
            _this._disable();
        } else {
            this.get().done(function () {
                _this._disable();
            });
        };
    }

}

paramPamPam.enable();


Как его можно упросить ? Писать в каждом методе на подобии enable и disable, не радует.
  • Вопрос задан
  • 280 просмотров
Решения вопроса 1
Petroveg
@Petroveg
Миром правят маленькие с#@&ки
Что-то вы напридумывали, причём даже не избыточное, а ещё и неработающее.
Для начала вам нужно разобраться с Promise, о чём уже сказал Алексей Уколов, а потом почитать про Deferred Object, раз уж используете jQuery. Для справки — этот объект создаётся при вызове ajax() автоматически.

Вы используете в Deferred Object один и тот же метод done(), который вызывается только в случае успешного ответа. Вам следует открыть для себя методы fail(), который вызывается в случае провала, и always(), который вызывается всегда, независимо от результата.

$.ajax({
	url: '...'
}).done(function (data) {
	console.log('Успех');
}).fail(function (data) {
	console.log('Провал');
}).always(function (data) {
	console.log('А мне пофигу');
});

Update: Не ручаюсь за безукоризненность кода. Возможно, использование двух Deferred не есть гуд.
На скорую руку, примерно вот так (при нескольких обращениях подряд к методу запрос будет всё равно один):

var paramPamPam = {
	data: null,
	defer: $.Deferred(),

	get: function () {
		if (this.data) {
			this.defer.resolve(this.data);
		} else {
			if (!this.transport) {
				this.transport = $.ajax({
					url: '...',
					type: 'post'
				});
			}

			this.transport
				.done(this.enable.bind(this))
				.fail(this.disable.bind(this))
				.always(function () {
					delete this.transport;
				}.bind(this));
		};

		return this.defer.promise();
	},

	enable: function (data) {
		this.data = data;
		this.defer.resolve(data);
	},

	disable: function () {
		this.defer.resolve();
	}
}

paramPamPam.get().then(function (data) {
	console.log(data);
});

paramPamPam.get().then(function (data) {
	console.log(data);
});
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы