javascript

27 декабря 2022 г. 9:32

Websockets

ws, WebSocket - протокол для общения между клиентом и сервером, предоставляющий двухсторонне общение сверх протокола TCP.

Мы подключаем WebSocket один раз, а затем сервер может отдавать нам ответы тогда, когда посчитает нужным.

Сначала отправляется обычный TCP-запрос на сервер и ждём от него ответа. Такой процесс называется “рукопожатие” (Handshake) (используется также при подключении к роутеру). Затем после получении ответа идёт переключение протокола на WebSocket, сигнализируя о том, что сервер будет присылать ответы множество раз.

Пример:

// Отправляем запрос серверу по ссылке example.com/connect-to-ws
// Вот что примерно мы пришлём:
GET /connect-to-ws HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

// А вот что нам на такой запрос ответит сервер при успешном рукопожатии:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Особенности WS:

  • Поддерживает двухсторонее соединение в реальном времени
  • Отправляет заголовок только один раз
  • Нет ограничений, связанных с кросс-доменными запросами
  • Могут отправлять/получать как строки, так и бинарные данные

API

Методы:

  • socket.send(data),
  • socket.close([code], [reason]).

События:

  • open,
  • message,
  • error,
  • close.

Привязка контекста к функции

let boundFunc = func.bind(context);

Результатом вызова func.bind(context) является особый «экзотический объект» (термин взят из спецификации), который вызывается как функция и прозрачно передаёт вызов в func, при этом устанавливая this=context.

Другими словами, вызов boundFunc подобен вызову func с фиксированным this.

Например, здесь funcUser передаёт вызов в func, фиксируя this=user:

let user = {
  firstName: "Вася"
};

function func() {
  alert(this.firstName);
}

let funcUser = func.bind(user);
funcUser(); // Вася

 

let user = {
  firstName: "Вася",
  say(phrase) {
    alert(`${phrase}, ${this.firstName}!`);
  }
};

let say = user.say.bind(user);

say("Привет"); // Привет, Вася (аргумент "Привет" передан в функцию "say")
say("Пока"); // Пока, Вася (аргумент "Пока" передан в функцию "say")

Частичное применение

let bound = func.bind(context, [arg1], [arg2], ...);

 

function mul(a, b) {
  return a * b;
}

let double = mul.bind(null, 2);

alert( double(3) ); // = mul(2, 3) = 6
alert( double(4) ); // = mul(2, 4) = 8
alert( double(5) ); // = mul(2, 5) = 10

Частичное применение без контекста

function partial(func, ...argsBound) {
  return function(...args) { // (*)
    return func.call(this, ...argsBound, ...args);
  }
}

// использование:
let user = {
  firstName: "John",
  say(time, phrase) {
    alert(`[${time}] ${this.firstName}: ${phrase}!`);
  }
};

// добавляем частично применённый метод с фиксированным временем
user.sayNow = partial(user.say, new Date().getHours() + ':' + new Date().getMinutes());

user.sayNow("Hello");
// Что-то вроде этого:
// [10:00] John: Hello!

Можем ли мы изменить this дополнительным связыванием?

function f() {
  alert(this.name);
}

f = f.bind( {name: "Вася"} ).bind( {name: "Петя" } );

f();

Ответ: Вася.

Экзотический объект bound function, возвращаемый при первом вызове f.bind(...), запоминает контекст (и аргументы, если они были переданы) только во время создания.

Следующий вызов bind будет устанавливать контекст уже для этого объекта. Это ни на что не повлияет.

Можно сделать новую привязку, но нельзя изменить существующую.

Примеры

Пример 1

function f() {
  alert(this.name);
}

f = f.bind( {name: "Вася"} ).bind( {name: "Петя"} );

f(); // Вася

Экзотический объект bound function, возвращаемый при первом вызове f.bind(...), запоминает контекст (и аргументы, если они были переданы) только во время создания.

Следующий вызов bind будет устанавливать контекст уже для этого объекта. Это ни на что не повлияет.

Можно сделать новую привязку, но нельзя изменить существующую.

Пример 2

function askPassword(ok, fail) {
  // let password = prompt("Password?", '');
  let password = "rockstar";
  if (password == "rockstar") ok();
  else fail();
}

let user = {
  name: 'Вася',

  loginOk() {
    console.log(`${this.name} logged in`);
  },

  loginFail() {
    console.log(`${this.name} failed to log in`);
  },

};

let login_ok = user.loginOk.bind(user);
let login_fail = user.loginFail.bind(user);

askPassword(login_ok, login_fail);

Пример 3

function askPassword(ok, fail) {
  // let password = prompt("Password?", '');
  let password = "rockstar";
  if (password == "rockstar") ok();
  else fail();
}

let user = {
  name: 'John',

  login(result) {
    console.log( this.name + (result ? ' logged in' : ' failed to log in') );
  }
};


askPassword(user.login.bind(user, true), user.login.bind(user, false));

Такой же результат через partial.

function partial(func, ...argsBound) {
  return function(...args) { // (*)
    return func.call(this, ...argsBound, ...args);
  }
}

function askPassword(ok, fail) {
  // let password = prompt("Password?", '');
  let password = "rockstar";
  if (password == "rockstar") ok();
  else fail();
}

let user = {
  name: 'John',

  login(result) {
    console.log( this.name + (result ? ' logged in' : ' failed to log in') );
  }
};


user.ok = partial(user.login.bind(user), true)
user.fail = partial(user.login.bind(user), false)

askPassword(user.ok, user.fail);

Отличие preventDefault от stopPropagation?

preventDefault запрещает стандартное поведение элемента.

Примеры:
1. Клик на кнопку submit производит отправку формы, но preventDeafult() это прекратит.
2. Нажатие на ссылку перенаправляет на другую страницу, но preventDefault() запретит это действие.

stopPropagation запрещает передачу события от ребенка к родителю. Другими словами, если мы кликнули по вложенному элементу, его родитель "не почувствует" этого нажатия.

Пример:
Кнопки поверх картинки в слайдере на странице покупки товара. Если кликаем по картинке, открывается во весь экран, но если по кнопке, то какое-то другое действие, например, заказать товар.

Источники

  1. https://habr.com/ru/sandbox/171066/
  2. https://learn.javascript.ru/websocket
  3. https://learn.javascript.ru/bind

Оцените статью

0 из 5 (всего 0 оценок)

captcha
Отмеченные звёздочкой поля ( * ) являются обязательными для заполнения.

Спасибо за ваш отзыв!

После нажатия кнопки "Отправить" ваше сообщение будет доставлено мне на почту.

Автор статьи

Артём Мальцев

Веб-разработчик, владеющий знаниями языка программирования Python, фреймворка Django, системы управления содержимым сайта Django CMS, платформы для создания интернет-магазина Django Shop и многих различных приложений, использующих эти технологии.

Права на использование материала, расположенного на этой странице https://vivazzi.pro/ru/it/it-cheat-sheets/js/:

Разрешается копировать материал с указанием её автора и ссылки на оригинал без использования параметра rel="nofollow" в теге <a>. Использование:

Автор статьи: Артём Мальцев
Ссылка на статью: <a href="https://vivazzi.pro/ru/it/it-cheat-sheets/js/">https://vivazzi.pro/ru/it/it-cheat-sheets/js/</a>

Больше: Правила использования сайта

Представляю вашему вниманию книгу, написанную моим близким другом Максимом Макуриным: Секреты эффективного управления ассортиментом.

Книга предназначается для широкого круга читателей и, по мнению автора, будет полезна специалистам отдела закупок и логистики, категорийным и финансовым менеджерам, менеджерам по продажам, аналитикам, руководителям и директорам, в компетенции которых принятие решений по управлению ассортиментом.

Комментарии: 0

Вы можете оставить комментарий как незарегистрированный пользователь.

Но зарегистрировавшись, вы сможете:

  • получать оповещения об ответах
  • просматривать свои комментарии
  • иметь возможность использовать все функции разработанных сервисов

Для комментирования от своего имени войдите или зарегистрируйтесь на сайте Vuspace

Отправить

На данный момент нет специального поиска, поэтому я предлагаю воспользоваться обычной поисковой системой, например, Google, добавив "vivazzi" после своего запроса.

Попробуйте

Выберите валюту для отображения денежных единиц