В JavaScript очень популярны связанные вызовы методов, и друзья, использующие jQuery, должны глубоко это понимать. Более подробно этот метод описан в разделе «Шаблоны проектирования Javascript». Чтобы реализовать цепочку вызовов методов, вам нужно только позволить методам, определенным в прототипе, возвращать ссылки на объекты экземпляра, которые вызывают эти методы. Посмотрите в книге «Это». код:
(функция() {
функция _$(els) {
this.elements = [];
for (var i = 0, len = els.length; i < len; ++i) {
элемент вар = els[i];
if (typeof element == 'string') {
элемент = document.getElementById(элемент);
}
this.elements.push(элемент);
}
};
_$.прототип = {
каждый: функция (fn) {
for (var i = 0, len = this.elements.length; i <len; ++i) {
fn.call(this, this.elements[i]);
}
верните это;
},
setStyle: function(prop, val) {
this.each(function(el) {
el.style[prop] = значение;
});
верните это;
},
показать: функция() {
вар, что = это;
this.each(function(el) {
that.setStyle('display', 'block');
});
верните это;
},
addEvent: функция (тип, fn) {
вар добавить = функция (эл) {
если (window.addEventListener) {
el.addEventListener(тип, fn, false);
}
иначе, если (window.attachEvent) {
el.attachEvent('on'+type, fn);
}
};
this.each(function(el) {
добавить (эл);
});
верните это;
}
};
окно.$ = функция() {
вернуть новый _$(аргументы);
};
})();
Как видите, каждый метод заканчивается фразой «return this», которая передает объект вызывающего метода следующему методу в цепочке. Однако если данные, которыми мы хотим оперировать, получены посредством асинхронного запроса, как сохранить цепочку вызовов методов? Дастин Диас предоставляет нам способ обеспечить цепочку вызовов методов. Он также является одним из авторов книги «Шаблоны проектирования Javascript».
Он впервые сконструировал объект Queue, а именно:
Затем используйте его как инструмент для построения цепочки очередей асинхронных методов. С помощью этого инструмента легко создать плагин jQuery, который извлекает контент с сервера и добавляет его в селектор.
Таким образом, мы можем асинхронно получать контент и продолжать цепочку вызовов.
$("<дел/>")
.fetch('/server/navigation.html')
.addClass('столбец')
.appendTo('#side');
Посетите демонстрационную страницу, чтобы увидеть эффект.
Что делать, если в очереди много элементов, ожидающих ответа на стороне сервера? Автор сконструировал такой метод, на который стоит обратить внимание:
Таким образом, мы можем вызвать его следующим образом:
fetchTweet(url).linkify().filterBadWords().appendTo('#status');
На данный момент мы уже знаем, как реализовать асинхронную цепочку методов, но стоит задуматься над некоторыми вопросами, поднятыми некоторыми комментариями в конце статьи « Асинхронная цепочка очередей методов в JavaScript ». Плагину $.fn.fetch нужно только добавить возвращаемое содержимое к элементу. Нужна ли очередь? Более того, $.fn.load в jQuery можно полностью реализовать. Если в Queue используется только одна функция обратного вызова, ее можно записать так:
(функция($) {
$.fn.fetch = функция (url) {
вар очередь = новая очередь;
this.each(function() {
вар эль = это;
$.ajax({
URL: URL,
введите: «получить»,
Тип данных: 'JSON',
успех: функция (соответственно) {
$(el).html(соответственно['text1']);
}
});
});
верните это;
};
}) (jQuery);
Интересно, что ты думаешь?
функция fetchTweet(url) {
this.queue = новая очередь;
this.tweet = "";
вар сам = это;
ajax(url, функция(соответственно) {
self.tweet = соответственно;
self.queue.flush(это);
});
}
fetchTweet.prototype = {
связать: функция() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/b@(w{1,20}b/g, '$1');
});
верните это;
},
filterBadWords: function() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/b(fuck|shit|piss)b/g, "");
});
верните это;
},
AppendTo: функция (селектор) {
this.queue.add(function(self) {
$(self.tweet).appendTo(селектор);
});
верните это;
}
};
(функция($) {
$.fn.fetch = функция (url) {
вар очередь = новая очередь;
this.each(function() {
вар эль = это;
очередь.add(функция(соответственно) {
$(эл).html(соответственно);
});
});
$.ajax({
URL: URL,
Тип данных: 'html',
успех: функция (html) {
очередь.flush(html);
}
});
верните это;
};
}) (jQuery);
функция Очередь() {
// сохраняем ваши обратные вызовы
this._methods = [];
// сохраняем ссылку на ваш ответ
this._response = ноль;
// все очереди начинаются без очистки
this._flushed = ложь;
}
Очередь.прототип = {
//добавляем обратные вызовы в вашу очередь
добавить: функция (фн) {
// если очередь была очищена, немедленно возвращаемся
если (this._flushed) {
fn(this._response);
// иначе помещаем его в очередь
} еще {
this._methods.push(fn);
}
},
флеш: функция (соответственно) {
// примечание: сброс происходит только один раз
если (this._flushed) {
возвращаться;
}
// сохраняем ваш ответ для последующих вызовов после флеш()
this._response = соответственно;
// отмечаем, что он был сброшен
this._flushed = правда;
// выдвигаем их и перезваниваем
пока (this._methods[0]) {
this._methods.shift()(соответственно);
}
}
};