представлять
Мост -режим отделяет абстрактные части от своих частей реализации, так что все они могут варьироваться независимо.
текст
Режим моста чаще всего используется в мониторинге событий. Давайте сначала посмотрим на кусок кода:
Кода -копия выглядит следующим образом:
addEvent (element, 'click', getbeerbyid);
функция getBeerbyId (e) {
var id = this.id;
Asyncrequest ('Get', 'Beer.uri? Id =' + id, function (resp) {
// Ответ обратного вызова.
console.log ('запрошенное пиво:' + resp.responsetext);
});
}
Существует проблема с приведенным выше кодом, что GetBeerByID должен иметь контекст браузера, который будет использоваться, поскольку он использует это свойство. Если контекст не используется, то это будет остановка. Поэтому, как правило, небольшой опытный программист преобразует программу в следующую форму:
Кода -копия выглядит следующим образом:
функция getBeerbyId (id, обратный вызов) {
// Отправить запрос через идентификатор и вернуть данные
Asyncrequest ('Get', 'Beer.uri? Id =' + id, function (resp) {
// Ответ обратного вызова
обратный вызов (Resp.ResponseText);
});
}
Более практично, верно? Во -первых, идентификатор может быть передан по желанию, и функция обратного вызова также предоставлена для пользовательской функции обработки. Но какое это имеет отношение к мощности? Это то, что будет отражать следующий код:
Кода -копия выглядит следующим образом:
addEvent (element, 'click', getbeerbyidbridge);
функция getBeerbyIdbridge (e) {
getBeerbyId (this.id, function (пиво) {
console.log («Запрашиваемое пиво: '+пиво);
});
}
Здесь GetBeerByIdbridge - это мост, который мы определяем, который используется для подключения Abstract Click Event и GetBeerByID, и в то же время передавать идентификатор источника события и функцию индивидуальной вызова (консоль.
Этот пример выглядит немного просто, давайте возьмем еще один более сложный практический пример.
Фактическая очередь соединения XHR
Мы хотим построить очередь, которая хранит много запросов AJAX в очереди. Использование очередей в основном потому, что мы должны убедиться, что соединенные запросы обрабатываются в первую очередь. В любое время мы можем приостановить запросы, удалять запросы, повторно запросов и поддержать события подписки на каждый запрос.
Основные основные функции
До официального начала давайте определим несколько основных функций инкапсуляции. Во -первых, первая - это инкапсуляция функции асинхронных запросов:
Кода -копия выглядит следующим образом:
var asyncrequest = (function () {
функция handlereAdystate (o, обратный вызов) {
var poll = window.setInterval (
function () {
if (o && o.readystate == 4) {
window.clearinterval (опрос);
if (обратный вызов) {
обратный вызов (O);
}
}
},
50
);
}
var getExhr = function () {
var http;
пытаться {
http = new xmlhttprequest;
getExhr = function () {
вернуть новый xmlhttprequest;
};
}
поймать (e) {
var msxml = [
'Msxml2.xmlhttp.3.0',
'Msxml2.xmlhttp',
'Microsoft.xmlhttp'
];
for (var i = 0, len = msxml.length; i <len; ++ i) {
пытаться {
http = new ActivexObject (msxml [i]);
getExhr = function () {
вернуть новый ActivexObject (msxml [i]);
};
перерыв;
}
поймать (e) {}
}
}
вернуть http;
};
возврат функции (метод, URI, обратный вызов, postdata) {
var http = getxhr ();
http.open (метод, uri, true);
HandlerEadyState (http, обратный вызов);
http.send (postdata || null);
вернуть http;
};
}) ();
Функция инкапсулированной самообслуживания является общей функцией запроса AJAX, и я считаю, что любой, у кого есть атрибут Ajax, может понять это.
Далее мы определяем общий метод для добавления методов (функции):
Кода -копия выглядит следующим образом:
Function.prototype.method = function (name, fn) {
this.prototype [name] = fn;
вернуть это;
};
Наконец, добавьте 2 метода о массивах, один для обхода и один для фильтрации:
Кода -копия выглядит следующим образом:
if (! array.prototype.foreach) {
Array.method ('foreach', function (fn, thisobj) {
var scope = thisObj || окно;
for (var i = 0, len = this.length; i <len; ++ i) {
fn.call (Scope, это [i], i, this);
}
});
}
if (! array.prototype.filter) {
Array.method ('filter', function (fn, thisobj) {
var scope = thisObj || окно;
var a = [];
for (var i = 0, len = this.length; i <len; ++ i) {
if (! fn.call (scope, это [i], i, это)) {
продолжать;
}
A.Push (это [i]);
}
вернуть А;
});
}
Поскольку некоторые новые браузеры уже поддерживают эти две функции (или некоторые библиотеки классов уже поддерживают их), мы должны сначала судить, если они уже поддерживаются, и если они уже поддерживаются, они больше не будут обрабатываться.
Система наблюдателя
Наблюдатели играют важную роль в процессе событий в очереди и могут подписаться на события при очереди (успех, неудача, ожидание):
Кода -копия выглядит следующим образом:
window.ded = window.ded || {};
Ded.util = ded.util || {};
Ded.util.observer = function () {
this.fns = [];
}
Ded.util.observer.prototype = {
Подписаться: function (fn) {
this.fns.push (fn);
},
USOUBSCRIBE: function (fn) {
this.fns = this.fns.filter (
функция (El) {
if (el! == fn) {
вернуть Эль;
}
}
);
},
Fire: function (o) {
this.fns.foreach (
функция (El) {
el (o);
}
);
}
};
Основной код реализации очередей
Во -первых, вы подписываетесь на основные атрибуты и делегаты в очереди:
Кода -копия выглядит следующим образом:
Ded.queue = function () {
// содержит очередь для запросов.
this.queue = [];
// Использовать наблюдаемый объект на 3 разных состояниях, чтобы вы могли подписаться на события в любое время
this.oncomplete = new ded.util.observer;
this.onfailure = new ded.util.observer;
this.onflush = new ded.util.observer;
// основные свойства могут быть установлены во время внешних вызовов
this.retrycount = 3;
this.currentretry = 0;
this.paused = false;
this.imeout = 5000;
this.conn = {};
this.imer = {};
};
Затем, через цепому вызову ded.queue.method, в очередь добавлено много доступных методов:
Кода -копия выглядит следующим образом:
Ded.queue.
Method ('flush', function () {
// метод промывки
if (! this.queue.length> 0) {
возвращаться;
}
if (this.paused) {
this.paused = false;
возвращаться;
}
var that = это;
this.currentretry ++;
var Abort = function () {
that.conn.abort ();
if (that.currentretry == that.retrycount) {
that.onfailure.fire ();
that.currentretry = 0;
} еще {
that.flush ();
}
};
this.timer = window.settimeout (Abort, this.Timeout);
var callback = function (o) {
window.cleartimeout (that.timer);
that.currentretry = 0;
that.queue.shift ();
that.onflush.fire (o.responsetext);
if (that.queue.length == 0) {
that.oncomplete.fire ();
возвращаться;
}
// рекурсивный призыв к промыванию
that.flush ();
};
this.conn = asyncrequest (
this.queue [0] ['method'],
this.queue [0] ['uri'],
перезвонить,
this.queue [0] ['params']
);
}).
method ('setretrycount', function (count) {
this.retrycount = count;
}).
method ('settimeout', function (time) {
this.imeout = время;
}).
Method ('add', function (o) {
this.queue.push (o);
}).
Method ('pause', function () {
this.paused = true;
}).
Method ('dequeue', function () {
this.queue.pop ();
}).
method ('clear', function () {
this.queue = [];
});
Код выглядит много, и после складывания вы можете обнаружить, что он на самом деле определяется на очереди с помощью промывки, setretrycount, settimeout, добавления, паузы, dequeue и четких методов.
Простой звонок
Кода -копия выглядит следующим образом:
var q = new ded.queue;
// Установите количество повторений немного выше, чтобы справиться с медленными соединениями
Q.setretryCount (5);
// установить время ожидания
Q.SetTimeout (1000);
// Добавить 2 запроса.
Q.Add ({
Метод: 'Get',
uri: '/path/to/file.php?ajax=true'
});
Q.Add ({
Метод: 'Get',
uri: '/path/to/file.php?ajax=true&woe=me'
});
// Очередь промывки
Q.flush ();
// остановив очередь и сохранить оставшиеся
Q.pause ();
// Прозрачный.
Q.clear ();
// Добавить 2 запроса.
Q.Add ({
Метод: 'Get',
uri: '/path/to/file.php?ajax=true'
});
Q.Add ({
Метод: 'Get',
uri: '/path/to/file.php?ajax=true&woe=me'
});
// Удалить последний запрос из очереди.
Q.Dequeue ();
// снова
Q.flush ();
Где мост?
В коде вызовов выше нет моста, так что насчет моста? Взгляните на полный пример ниже, и вы обнаружите, что везде есть мосты:
Кода -копия выглядит следующим образом:
<! Doctype html public "-// w3c // dtd html 4.01 // en"
"http://www.w3.org/tr/html4/strict.dtd">
<html>
<голова>
<meta http-equiv = "content-type" content = "text/html; charset = utf-8">
<title> ajax connection queue </title>
<script src = "utils.js"> </script>
<script src = "queue.js"> </script>
<script type = "text/javascript">
addEvent (window, 'load', function () {
// выполнить.
var q = new ded.queue;
Q.setretryCount (5);
Q.SetTimeout (3000);
var items = $ ('items');
var results = $ ('результаты');
var keeue = $ ('queue-items');
// Сохранить отслеживание вашего запроса на клиенте
var запросы = [];
// после каждого запроса на промывку подпишитесь на специальные шаги обработки
Q.onflush.subscribe (function (data) {
Results.innerhtml = data;
requests.shift ();
queue.innerhtml = requests.tostring ();
});
// Шаги обработки времени подписки
Q.onfailure.subscribe (function () {
Results.innerhtml += '<span style = "color: red;"> ошибка соединения! </span>';
});
// подписаться на все успешные шаги обработки x
Q.Oncomplete.subscribe (function () {
Results.innerhtml += '<span style = "color: green;"> завершен! </span>';
});
var actionDispatcher = function (element) {
Switch (элемент) {
Case 'Flush':
Q.flush ();
перерыв;
Case 'dequeue':
Q.Dequeue ();
requests.pop ();
queue.innerhtml = requests.tostring ();
перерыв;
Дело «пауза»:
Q.pause ();
перерыв;
case 'clear':
Q.clear ();
запросы = [];
queue.innerhtml = '';
перерыв;
}
};
var AddRequest = function (запрос) {
var data = request.split ('-') [1];
Q.Add ({
Метод: 'Get',
URI: 'Bridge-Connection-queue.php? ajax = true & s =' + data,
Парамы: NULL
});
requests.push (data);
queue.innerhtml = requests.tostring ();
};
addEvent (элементы, 'нажмите', function (e) {
var e = e || window.event;
var src = e.target || E.srcelement;
пытаться {
e.preventdefault ();
}
поймать (ex) {
E. ReturnValue = false;
}
ActionDispatcher (src.id);
});
var Adders = $ ('Adders');
addEvent (Adders, 'Щелкни «нажмите», функция (e) {
var e = e || window.event;
var src = e.target || E.srcelement;
пытаться {
e.preventdefault ();
}
поймать (ex) {
E. ReturnValue = false;
}
addRequest (src.id);
});
});
</script>
<style type = "text/css" media = "screen">
Тело
{
Шрифт: 100% Грузия, Times, Serif;
}
H1, H2
{
шрифт-вес: нормальный;
}
#очередь
{
высота: 1,5 эма;
}
#Добавить
{
Подкладка: .5em;
Фон: #DDD;
Граница: 1PX SOLID #BBB;
}
#Результаты
{
Подкладка: .5em;
Граница: 1PX SOLID #BBB;
}
</style>
</head>
<body id = "Пример">
<div id = "doc">
<h1>
Асинхронная запрос на соединение </h1>
<div id = "queue-items">
</div>
<div id = "add-stuff">
<h2> Добавьте новый запрос в очередь </h2>
<ul id = "Adders">
<li> <a href = "#" id = "action-01"> добавить "01" в очередь </a> </li>
<li> <a href = "#" id = "action-02"> добавить "02" в очередь </a> </li>
<li> <a href = "#" id = "action-03"> добавить "03" в очередь </a> </li>
</ul>
</div>
<h2> Quote Control </h2>
<ul id = 'items'>
<li> <a href = "#" id = "flush"> flush </a> </li>
<li> <a href = "#" id = "dequeue"> dequeue </a> </li>
<li> <a href = "#" id = "pause"> пауза </a> </li>
<li> <a href = "#" id = "clear"> ясно ясно </a> </li>
</ul>
<div id = "Результат-район">
<h2>
результат:
</h2>
<div id = "Результаты">
</div>
</div>
</div>
</body>
</html>
В этом примере вы можете выполнять различные действия, такие как очереди промывки, очереди паузы, удаление запросов в очереди, четкие очереди и т. Д. В то же время, я считаю, что каждый также испытывал силу мостов.
Суммировать
Преимущества режима моста также очевидны. Мы перечислим только несколько основных преимуществ:
1. Разделите интерфейс и детали реализации. Реализация не может быть связана с интерфейсом неизменно. Реализация абстрактного класса (функция) может быть настроена во время выполнения, и объект может даже изменить свою реализацию во время выполнения. Он также полностью разворачивает абстракцию и реализацию, которая также способствует слои, тем самым генерируя лучшую структурированную систему.
2. Улучшить масштабируемость
3. Детали реализации прозрачны для клиентов и могут скрывать данные о реализации от клиентов.
В то же время режим моста также имеет свои недостатки:
Большое количество классов приведет к увеличению затрат на разработку, а также может снизить производительность.