Pay attention to “songbao write code”, selected good articles, a question of the day

Saucxs | songEagle

2020, real “rat” is not easy

In 2021, “niu” changes the world

When the wind is strong and the tide is surging, the heavy task must be bravely hoof!

One, foreword

This topic covers JavaScript, Node, Vue, React, browser, HTTP, etc.

Interviewer: What about the understanding of webSockets in JS?

This is a very broad question, how to answer the highlight?

Web Sockets Encapsulation case

Web Sockets Encapsulation example:

Here is the Event code:

Constructor (CTX) {this._events = {} this._ctx = CTX} /** * Bind an Event * @param name The Event name * @param cb callback * @param CTX context * @returns {Event} */ on (name, cb, CTX) {return eventsOnApi(this, name, cb, CTX @param CTX context * @returns {Event} */ once (name, cb, ctx) { return eventsOnApi(this, name, cb, ctx, @param CTX context * @param CTX context * @returns {Event} */ off (name, cb, ctx) { var events = eventsApi(this, name, cb, ctx) for (var key in events) { var e = this._events[key] events[key].slice().forEach(function (item) { E.ice (e.indexof (item), 1)})} return this} Off * @param name * @param cb * @param CTX */ Pause (name, cb, CTX) {return eventsPauseApi(this, name, cb, CTX, } /** * resume an event, continue to trigger the callback, Off * @param name * @param cb * @param CTX */ resume (name, cb, CTX) {return eventsPauseApi(this, name, cb, CTX, false) } emit (name) { var _this = this if (! name || typeof name ! == 'string') return this var len = arguments.length var args = [] var i = 1 while (i < len) { args.push(arguments[i++]) } name.split(/\s+/).forEach(function (ename) { if (ename && _this._events[ename]) { _this._events[ename].slice().forEach(function (handler) { if (handler.once) { handler.cb.apply(handler.ctx, args) _this.off(ename, handler.cb, handler.ctx) } else if (! Handler.pause) {handler.cb.apply(handler.ctx, args)}})}}) return this}} /** * * @param self Event instance * @param name Event name, * @param CTX binds the context of the callback function * @return events */ function eventsApi (self, name, cb, CTX) {var events = {} If (name) {name.split(/\s+/).foreach (function (ename) {if (ename && self._events[ename]) { events[ename] = self._events[ename] } }) } else { for (var key in self._events) { events[key] = self._events[key] } } var keys = Object.keys(events) if (keys.length === 0) return events if (cb && typeof cb === 'function') { keys.forEach(function (key) { events[key] = events[key].filter(function (e) { return e.cb === cb }) }) } if (ctx) { keys.forEach(function (key) { events[key] = events[key].filter(function (e) { return e.ctx === ctx }) }) } return events } function eventsPauseApi (self, name, cb, CTX, pause) {var events = eventsApi(self, name, cb, ctx) for (var key in events) { events[key].forEach(function (item) { item.pause = pause }) } return self } /** * on,once @param self Event instance @param name Event name, Can be multiple event names separated by Spaces * @param cb callback function * @param CTX binding callback function context * @param once is once * @return self */ function eventsOnApi (self, name, cb, ctx, once) { if (! name || typeof cb ! == 'function' || typeof name ! == 'string') return self name.split(/\s+/).forEach(function (ename) { var handlers = self._events[ename] || [] handlers.push({ cb: cb, ctx: ctx || self._ctx, pause: false, once: once }) self._events[ename] = handlers }) return self } export default EventCopy the code

This is the WebSockets code:

import Event from './event.js' const settings = { url: null, protocols: null, debug: Open automaticOpen: true, // Automatically try to connect to automaticReconnect: True, // Interval for each connection attempt reconnectInterval: 1000, // Maximum delay interval for connection attempts maxReconnectInterval: 30000, // Ratio of retry attempts reconnectDecay: 1.5, // Connection timeout event, ms value timeoutInterval: 2000, // Maximum number of connections maxReconnectAttempts: Null, // binaryType, default blob, or arraybuffer binaryType: 'blob' } class WebSocketIO extends Event { constructor (url, protocols, Options = {}) {super() if (isPlainObject(protocols)) {options = protocols protocols = null} // Set the configuration This.setconfig (options) this.url = url // Can be a single protocol name string or an array of multiple protocol name strings. These strings are used to represent subprotocols, Protocols = protocols // Backend specified subprotocol this.protocol = null // Instance of WebSocket this. IO = null // Manually close this.forcedClose = false // Whether this. Active = true // Number of reconnection attempts this.reconnectAttempts = 0 // Data cache pool this.polls If (this.automaticOpen === true) {this.open(false)}} setConfig (options) {if (! IsPlainObject (options)) return for (let key in Settings) {if (typeof options[key]! == 'undefined') { this[key] = options[key] } else if (this[key] == null) { this[key] = settings[key] } } } start (options) { this.setConfig(options) this.open(false) } get readyState () { if (this.io) { return this.io.readyState } } Open (reconnectAttempt) {// An I/O instance has been destroyed or already exists. this.active || this.io) return try { this.io = new WebSocket(this.url, this.protocols) } catch (e) { this.emit('error', E) throw e} / / try to connect again the if (reconnectAttempt) {if (this. MaxReconnectAttempts && enclosing reconnectAttempts > Enclosing maxReconnectAttempts) {return}} else {this. ReconnectAttempts = 0} / / trigger connecting events, Emit ('connecting') log('attempt-connect', TimeId = setTimeout(() => {log('connection-timeout', this) this.timeoutClosed = true this.io.close() this.timeoutClosed = false }, TimeoutInterval) // Listen for WebSocket callback events attachEvent(this, this. IO, ReconnectAttempt)} // Send (data) {if (this.readyState === 1) {log('send data: ', data, this) return this.io. Send (data)} else {console.error('WebSocket instance does not exist, please try to reconnect ')}} // Write data, cache data, return 0: Direct send, greater than 0: cache, -1: Write (type, payload) {if (this.readyState === 1) {this.send(json.stringify ({type, Payload})) return 0} else if (this.active) {// Pay attention to memory leaks this.stringify ({type, JSON. payload })) return this.polls.length } return -1 } flush () { const polls = this.polls for (let i = 0, length = polls.length; i < length; i++) { this.send(polls[i]) } this.polls = [] } close (reason, code = 1000) { if (! this.active) return this.forcedClose = true if (this.io) { this.io.close(code, reason) } } destroy () { if (this.active) { this.close('destroy') this.active = false } } } function attachEvent (ws, io, reconnectAttempt) { io.onopen = function (e) { clearTimeout(ws.timeId) log('open', ws) this.reconnectAttempts = 0 ws.protocol = io.protocol ws.emit('open', e) ws.flush() } io.onclose = function (e) { clearTimeout(ws.timeId) ws.io = null if (ws.forcedClose) { ws.emit('close', e) if (! Ws.active) {// Destroy the object with destroy and empty the event ws._events = {}}} else {// Try again to intercept if (! reconnectAttempt && ! ws.timeoutClosed) { ws.emit('close', e) } if (! ws.automaticReconnect) return const timeout = ws.reconnectInterval * Math.pow(ws.reconnectDecay, ws.reconnectAttempts) setTimeout(function () { ws.reconnectAttempts++ ws.open(true) }, timeout > ws.maxReconnectInterval ? ws.maxReconnectInterval : timeout) } } io.onmessage = function (e) { log('onmessage: ', e.data, ws) ws.emit('message', e.data) if (typeof e.data === 'string') { try { const data = JSON.parse(e.data) if (data.type) { ws.emit(data.type, Data. Payload)}} catch (e) {log('onmessage ', ws)}} IO. Onerror = function (e) {log('onerror: ', e, ws) ws.emit('error', e) } } function log (... args) { const ws = args[args.length - 1] if (ws.debug) { const e = args.slice(0, args.length - 1) console.log(... e) } } function isObjectLike (obj) { return obj ! = null && typeof obj === 'object' } const objectProto = Object.prototype const toString = obj => objectProto.toString.call(obj) function isPlainObject (obj) { if (! isObjectLike(obj) || toString(obj) ! == '[object Object]') { return false } const proto = Object.getPrototypeOf(obj) if (proto === null) { return true } return proto.constructor === Object } export default WebSocketIOCopy the code

Web Sockets goal: To provide full-duplex, bidirectional communication over a single continuous connection

Web Sockets use a custom protocol, which, like HTTP, is an application-layer protocol

The benefits are:

  • Be able to send very small amounts of data on the client side, server side, don’t worryHTTP byte levelThe cost of
  • Delivering packets is smaller and more suitable for mobile terminals, where bandwidth and network latency are key issues

The downside: it takes longer to write a protocol than it takes to write a JS API

Differences from HTTP:

  • HTTP can only be initiated by the client, and webSocket is two-way
  • WebSocket transmits packets that are relatively small compared to HTTP and are suitable for mobile use
  • Resources can be shared across domains without origin restrictions

Supported browsers: Firfox6+ Safari5+ Chrome IOS 4+ Safari

4. WebSockets usage

Create WebSockets instance

var ws = new WebSockets('ws://example.com')
Copy the code

Note that:

  • URL pattern:ws://, in the case of encryption:wss://
  • It has to be an absolute URL, which is the full URL

2. As soon as the instance is created, a connection is attempted, similar to XMLHttpRequest, with a readyState attribute indicating the current state.

  • Websocket.opening (0) Establishing a connection
  • Websocket.open (1) The connection has been established
  • Websocket. CLOSEING(2) Closing the connection
  • Websocket.close (3) has closed the connection

3. Sending and receiving data Use the Send () method to send data. The message event is triggered when the data is received

ws.send('hello')
ws.onmessage = function (event) {
  console.log(event.data)
}
Copy the code

Note:

  • Send Indicates that data must be sent in plain text
  • The data returned by Message is also in string format
  • WebSocket objects do not support DOM2-level event listeners and must handle each event individually using Dom0-level

Other events

  • Triggered when open successfully establishes a connection
  • Error Triggered when an error occurs, the connection cannot continue
  • Close is emitted when a connection is closed, as long as the close event object has extra information
    • WasClean is explicitly closed
    • Code Indicates the status code returned by the server
    • Reason A string containing information returned by the server

Thank you for your support

1, if you like the article, you can “share, like, comment”.

2, author nickname: SaucXS, songEagle, Songbao write code. “Songbao write code” public number author, daily question, laboratory, etc. A bytedance engineer who loves to toss, is committed to the whole stack, and is working hard to grow, star Sea, the future can be expected. Inside push bytedance each department each post.

3, long press the picture below, pay attention to “Songbao write code”, it is to obtain the development knowledge system construction, selected articles, project actual combat, laboratory, a daily interview question, advanced learning, thinking about career development, involving JavaScript, Node, Vue, React, browser, HTTP and other fields, I hope it can help you. We grow up together

Previous “Question of the Day”

1. JavaScript && ES6

  • Interviewer :ES6 deconstruction of the value of the understanding?

  • Interviewer: What is the difference between prototype chain and constructor combination method inheritance and primitive type inheritance?

  • Interviewer: What is the main difference between var and const,let?

  • Interviewer: What about the binding of this in JS?

  • Q: What about the understanding of webSockets in JS?

  • Q: What do you understand about XMLHttpRequest objects in JAVASCRIPT?

  • Question 18: Ajax in JS extends Comet across domains?

  • Q: What is the understanding of event flow, event handler and event object in JS?

  • 第 16 题 : How to perform client detection comprehensively in JS?

  • Interviewer: What are the methods for judging the JS type?

  • Interviewer: Tell me about your creation and extension of JS objects

  • [‘1’, ‘2’, ‘3’]. Map (parseInt) output, the reason, and the extension?

  • Q: What is the execution process of the JS engine?

  • Q: What is the execution process of JS engine?

  • Q: Tell me more about the JS data type

  • Q: What is your understanding of ES6 proxy?

  • Interviewer: What is the difference between “for in” and “for of”?

  • 6. How can Async/Await Async/Await Async?

  • 3. “Question of the Day” The interviewer asks you what you think of Promise?

  • In ES6, why do we use Symbol?

2. Browser

  • 9. Doesn’t requestAnimationFrame smell good?

3, Vue

  • How does VUE data binding work?

4, HTML 5

  • 第 29题 : What is the new attribute of htML-HTML5?

5, the algorithm

  • Interviewer: What do you know about graph theory? (2)

  • Interviewer: What do you know about graph theory?

  • 第 27题 (27题) Algorithm: How to use multiple solutions to achieve a jump game?

  • 第 26题 : What is the longest common prefix?

  • 第 25题 : Heap data structure – the first K high frequency elements?

  • 第 24题 【 daily 1 题】(24题) Algorithm: Greedy algorithm – how to fuel around the world?

  • Question 4: How to find repetitive elements in a scientific and efficient way?

6, the Node

  • 第 23题 : Describe the Event Loop in detail?

7, the Http

  • 1. “How does an interview question trigger deep soul searching?”

4, red envelope 🧧 welfare

The Nuggets 2020 Creators List is two days down to voting.

Simplify the process and cast 18 votes directly from your mobile phone.

Step 1: Download the Nuggets APP, open the APP, click on the top of the home page [2020 Creators List] to enter, search saucXS, and vote X;

Step 2: Click the button to get votes for him, share it with me or the group, and then return to the APP to vote X again.

Step 3: Go back to wechat, click the link you just shared, click Vote, jump to login, after login, you can vote x again.

Step 4: In the background of “Songbao write code” reply me screenshots, then we lucky draw red envelopes, there are more surprises.