JavaScript series -- promise, generator, async and await

ALKAOUA 2021-05-03 18:22:56
javascript series promise generator async


Preface

The biggest difference between synchronous and asynchronous is :

  • Synchronization will block , After the above code is executed, the following code will be executed
  • Asynchrony doesn't block , Before the execution of the above code is completed, the execution of the following code has already started

We know JS It's a single-threaded language , So if there are long-running tasks ( Such as : Timer 、DOM event 、 Asynchronous request, etc ), If you think of these tasks as synchronous tasks , That's going to be very serious “ Blocking phenomenon ”, So browsers classify these tasks as asynchronous tasks ,JS When the engine thread encounters these asynchronous tasks , Meeting notice Other threads ( Such as : Timer thread 、 Event processing thread 、 Asynchronous request thread, etc ) To do , In the end, just put the final result feedback JS Engine thread is OK

good , So this one notice and feedback How to do it? ?

So there was JavaScript The asynchronous programming mode of :Promise、Generator、async / await

Let's take a look at how these methods do this work :

Promise

Promise What is it? ?

Print out... On the console Promise , It turns out that [native code] , The description is an official encapsulated function , The code is local

image.png Output at console Promise.prototype , It turns out that there are then 、catch 、finally Other methods

image.png Sum up , We put Promise Think of it as a constructor , Use new Keyword creation Promise One of the simplest instance objects of p:

var p = new Promise((resolve,reject)=>{
if(1) resolve(" Asynchronous task completion ")
else reject(" Asynchronous task failed ")
})
 Copy code 

Output instance objects in the console p

image.png We're looking at instance objects p The prototype of the __proto__ I found it in the attributes Promise.prototype, So we can make instance objects p Use then / catch / finally Other methods

Promise The process of notification and feedback

notice

var p = new Promise((resolve,reject)=>{
if(1) resolve(" Asynchronous task completion ")
else reject(" Asynchronous task failed ")
})
 Copy code 

That's all Promise Of notice The process ,Promise Inside is an arrow function , The incoming parameter is resolve and reject,{ } The code running inside is resolve() and reject() Two operations that call other functions . The official rules : The parameters written in the front indicate “ Task to complete ”, Write in the second parameter to indicate “ Task failed ”. So you can see that : The names of these two parameters can be customized , It's just that we're trying to make it more semantic resolve and reject.

state

  1. We output instance objects on the console p, It shows a Promise object , In addition to the prototype, there are also [[PromiseState]] and [[PromiseResult]] Two attributes , As the name suggests, it means respectively state and result , The value of the state is fulfilled, and result The value of is that we just Promise It's written in the arrow function resolve() Arguments in parentheses " Asynchronous task completion "

image.png 2. So let's revise that Promise function , Control of its mission failed :

var p = new Promise((resolve,reject)=>{
if(0) resolve(" Asynchronous task completion ")
else reject(" Asynchronous task failed ")
})
 Copy code 

image.png 3. among [[PromiseResult]] We just Promise It's written in the arrow function reject() Arguments in parentheses " Asynchronous task failed ", and [[PromiseState]] Turned into rejected.

This illustrates the : During our notification process Promise The work behind it ( principle ) Namely : perform Promise When using the arrow function inside, the instance object will be p ( One Promise object ) Inside [[PromiseState]] Change the value of the property :

  • If you execute the first parameter (resolve) Corresponding function (resolve()) Words , Change the value of this property to fulfilled;( The source code is the truth )
  • If you execute the second parameter (reject) Corresponding function (reject()) Words , Change the value of this property to rejected
  1. What's the original value of this attribute , We use it setTimeout() Make a delay , To see :

image.png

  1. You can see that the original value of this property is pending.

feedback

  1. Let's look at instance objects p Use its inherited then Method :( This is an example of task completion )

image.png You can see the call p.then() After that, I return to a Promise object , And this object's state Turn into fulfilled, result Turn into undefined( Because I didn't call other functions and pass parameters )

  1. We use... For the example of task failure then() Method :

image.png

  1. You can find the state or rejected, And there's no printing res, explain p.then() It's not implemented , We're looking at this return Promise Object use catch() Method :

image.png 9. You can see the call p.then().catch() After that, I return to a Promise object , And this object's state Turn into fulfilled, result Turn into undefined, Also put err It's printed out

  1. This is the instance object p The essential reason why chaining can be used , It also proves why mission failure can only be executed catch() Method , And the mission is done then() Method will continue to execute the next one in the chain then() Method , Go all the way to catch() Reasons for not executing exit
  • then() Methodical The entrance key yes [[PromiseState]] The value of the property is fulfilled;
  • catch() Methodical The entrance key yes [[PromiseState]] The value of the property is rejected.( The source code is the truth )

image.png ( The task is completed p)

image.png ( The mission failed p)

summary

  • Use Promise Steps to solve asynchronous problems :
  1. Using constructors Promise Create instance object ;
  2. stay Write an arrow function in the constructor , Pass in two parameters , One represents the completion of the task , One represents mission failure ;
  3. Performing asynchronous tasks in arrow functions , After the execution is completed, the function with these two names is called , You can pass the execution result as an actual parameter ;
  4. Promise() After the asynchronous task of arrow function in is completed, it will return a Promise object , This object has been assigned to the instance object p;p You can use from Promise.prototype inherited then() / catch() Other methods
  5. p I'll see before I implement these methods [[PromiseState]] The value of this property depends on whether it enters the current method , Go in and come out [[PromiseState]] and [[PromiseResult]] The values of both properties can change ;
  6. After each execution, one is returned Promise object

After understanding the essence , about Promise The basic framework of the source code will probably know what it is ( Although it may be hard to understand now hhh), And the following uses 、 In the face of all kinds of scenes, I am quite sure .

It says Promise The essence of , Now let's look at Promise Source code , How to achieve “ notice ” and “ feedback ” Of , Students who want to skip directly Click here

Promise((resolve,reject)=>{}) Implementation principle of

  • Promise How does the inside know if it's successful , And it returns the result Promise Object's ?

Promise.then().catch() Implementation principle of

  • Why can chain
  • Why success will be then Methods capture ; Two is , Why are any mistakes catch Catch

Promise().then().catch() Handling multiple serial asynchronous tasks

For example, there is a need —— How many districts does a prefecture level city have :

  1. We have to call it now 【 Get local provinces 】 The interface of
  2. Get the provinces id And then it can call 【 Access to prefecture level cities 】 The interface of
  3. Get the corresponding prefecture level city id Before calling 【 How many districts does the prefecture level city have 】 The interface of

The pseudo code is as follows :

ajax('url_1',data1);
ajax('url_2',data2); // You need to get it before you can execute it ajax('url_1') Result 
ajax('url_3',data3); // You need to get it before you can execute it ajax('url_2') Result 
 Copy code 

According to the previous writing of callback function, it is :

ajax('url_1', data1, function (err, result) {
if (err) {
return handle(err);
}
ajax('url_2', data2, function (err, result) {
if (err) {
return handle(err);
}
ajax('url_3', data3, function (err, result) {
if (err) {
return handle(err);
}
return success(result);
});
});
});
 Copy code 

Not to mention its poor readability , If something goes wrong in the middle , It's hard for us to find out , It's also troublesome to modify . So we use Promise To solve this problem , The advantage is Promise The implementation of the serial execution of multiple asynchronous tasks written as synchronous task execution sequence

let promise = fn('url_1',data1)
promise.then(data2 => { // Note that there promise No parentheses , It's execution new Promise(...) An object returned after 
fn('url_2',data2)
}).then(data3 => {
fn('url_3',data3)
}).then(res =>{
console.log(res) // After serial, you can get the result you want 
}).catch(err => {
console.log(err)
})
function fn(url,data){
return new Promise((resovle,reject)=>{
ajax(url,data).success(function(res){
resolve(res)
})
})
}
 Copy code 

This makes the code much more readable , clear .( In fact, there are more concise methods behind )

That's it , that parallel What do I do ? When there are multiple asynchronous events , There's no connection between them, and there's no sequence , It just needs to be all done to get to work .

Serialization adds up the waiting time of each asynchronous event , Obviously there's a block to completion . So how can we make sure that all of them are completed in parallel ?

Promise.all And Promise.race The magic effect of

Promise.all([promise1,promise2,promise3,...])

  • Receive an array , Every item in an array is a promise object
  • When in an array be-all promise All of them are in the state of resolved When ,Promise.all The state of will become resolved
  • If one There is one promise The state of has become rejected, that Promise.all The state of will become rejected
  • call then When the result of the method is successful, the parameters of the callback function are also An array , According to the order Keep every one of them promise object resolve The value at execution time
let promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(1);
},4000)
});
let promise2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(2);
},3000)
});
let promise3 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(3);
},5000)
});
let promiseAll = Promise.all([promise1,promise2,promise3])
promiseAll.then(res=>{
console.log(res); // [1,2,3] 
}).catch(err => {
console.log(err);
})
 Copy code 

Console 5s After the output results :( The one with the longest execution time promise Finish is finish )

image.png The order is [1,2,3], Prove with which promise First of all, it becomes resolved irrelevant

let promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject(1);
},4000)
});
let promise2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(2);
},3000)
});
let promise3 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(3);
},5000)
});
let promiseAll = Promise.all([promise1,promise2,promise3]);
promiseAll.then(res => {
console.log(res);
}).catch(err => {
console.log(" Mission " + err + " failed ") // 1 That is the promise1 Asynchronous task execution failed in 
})
 Copy code 

Console 4s After the output results :( One of them promise Quit when you fail )

image.png

Promise.all() Implementation principle of :

Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let index = 0
let result = [] // Store the successful result of asynchronous task execution 
if (promises.length === 0) {
resolve(result)
} else {
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i]).then((data) => {
processValue(i, data) // Get the results of the task 
}, (err) => {
reject(err) // Once an error is found , Throw it right away 
return
})
}
function processValue(i, data) {
result[i] = data // Put the results of the task into the array 
if (++index === promise.length) {
// Every time it succeeds, the counter will add 1, Until everything is successful, it will be with values Consistent length , They are all successful 
resolve(result)
}
}
}
})
}
 Copy code 

summary :

  1. For each one of the arrays promise Object call then() Methods and catch() Methods test the results , Throw it as soon as you find an error
  2. If the current traversal promise The result of the object is successful , Then put in a results Array
  3. When results The length of the array is the same as the original promises Returns if the array length is the same results Array

Promise.race([promise1,promise2,promise3,...]) Racing mode

  • Accept that every one of them is promise Array of .
  • But with the all The difference is , first promise The object state becomes resolved The state of self becomes resolved, first promise become rejected The state of self becomes rejected. The first one became resolved Of promsie The value of will be used
let promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(1);
},4000)
});
let promise2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(2);
},3000)
});
let promise3 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(3);
},5000)
});
let promiseRace = Promise.race([promise1,promise2,promise3])
promiseRace.then(res => {
console.log(res); // Print out 2 because promise2 Finish first , The rest is ignored 
}).catch(err => {
console.log(" Mission " + err + " failed ");
})
 Copy code 

But on the console output promise1 and promise3 All show “ Task to complete ” The state of , in other words “ competition ” The loser will still finish the game

Promise.race() Implementation principle of

Promise.race = function (promises) {
return new Promise((resolve, reject) => {
let index = 0
let result = [] // Store the successful result of asynchronous task execution 
if (promises.length === 0) {
resolve(result)
} else {
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i]).then((data) => {
resolve(data) // One of the tasks is the result of the completion of the task , Throw it right away 
}, (err) => {
reject(err) // Once an error is found , Throw it right away 
return
})
}
function processValue(i, data) {
result[i] = data // Put the results of the task into the array 
if (++index === promise.length) {
// Every time it succeeds, the counter will add 1, Until everything is successful, it will be with values Consistent length , They are all successful 
resolve(result)
}
}
}
})
}
 Copy code 

summary :

  1. For each one of the arrays promise Object call then() Methods and catch() Methods test the results
  2. Once you find one of them promise Object is the state of completion of a task , Throw it right away
  3. Once you find one of them promise Object is the state of a task failure , Throw it right away

Promise The biggest problem is code redundancy , The original task was Promise It's packed , No matter what operation , It's all a pile at a glance then, The original meaning becomes very unclear . that , Is there a better way of writing ?

Generator

Generator What is it?

Generator( generator ) yes ES6 Standards introduce new data type . One generator It looks like a function , but You can return multiple times

function* fn(max) {
yield ...;
return;
}
 Copy code 

generator Generators look like functions , Unlike functions, we use function* Defined

yield keyword

keyword yield, It's kind of like return,yield and return The difference is that :

  • return Returns the value only after the function call ,return After statement You are not allowed to perform any Other operating
  • yield It is equivalent to pausing function execution and returning a value , Next call next() when , It will be executed until next yield sentence Where?

return The value returned

image.png Output at console return Value ( without return To the end of the function ) You'll get one generator object , Its properties [[GeneratorState]] The value of is suspended Express “ Pause state ”

Generator.prototype.next() Method

image.png Output at console generator The prototype of the object will see next、return、throw Other methods , Let's focus on next Method :

image.png Use g.next() Method gets an object {value: 1,done: false}, Now output g, It can be observed that its state is still suspended, When executing the third time g.next() You'll get {value: 1,done: false} object , Now output g The status of is "closed". Tell the outside world what to do generator Object has been executed

Back to value Namely yield The return value of ,done Express this generator Whether the execution is over . If done by true, be value Namely return The return value of . When executed done by true when , This generator The object has been executed , Don't call on next() 了 .

Generator.prototype.next() Method The ginseng

next() Methods can also be transferred to reference

function* gen(x){
var y = yield x + 2;
return y;
}
var g = gen(1);
g.next() // { value: 3, done: false }
g.next(2) // { value: 2, done: true }
 Copy code 

for the first time g.next() Output { value: 3, done: false } The reason is that gen(1) Pass in the parameter 1, then yield return 1 + 2, So get value The value is 3, And the second time g.next() Pass in the parameter 2, It's equivalent to putting the whole yield x + 2 Switch to 2, therefore return return y The value of is 2, end of execution ,done The value is true

Generator.prototype.return() Method

return() Method , Can return the given value , also Termination traversal Generator function

function* gen() {
yield 1;
yield 2;
yield 3;
}
var g = gen();
g.next() // { value: 1, done: false }
g.return('foo') // { value: "foo", done: true }
g.next() // { value: undefined, done: true }
 Copy code 

Generator.prototype.throw() Method

Generator The traverser object returned by the function , There is one. throw Method , Sure Throw an error outside the function , And then in Generator Function body capture

function* gen(x){
try {
var y = yield x + 2;
} catch (e){
console.log(e);
}
return y;
}
var g = gen(1);
g.next();
g.throw(' Something went wrong ');
// Something went wrong 
 Copy code 

It's equivalent to putting the whole yield x + 2 Replace statement with throw(" Something went wrong "), then try...catch... Statement captures , So output e

Generator Use

  • Output each term of the Fibonacci sequence

Take a famous Fibonacci sequence as an example to introduce :

0 1 1 2 3 5 8 13 21 34 ...
 Copy code 

To write a function that produces a Fibonacci sequence , It can be written like this :

function fib(max) {
var
t,
a = 0,
b = 1,
arr = [0, 1];
while (arr.length < max) {
[a, b] = [b, a + b];
arr.push(b);
}
return arr;
}
// test :
fib(5); // [0, 1, 1, 2, 3]
fib(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
 Copy code 

A normal function can only return once , So you have to return a Array. But sometimes we need to take one of the return values at a time , For example, make a user interaction platform Progress bar Ah, something like that , But ordinary functions can only return once , So we can't fulfill this requirement , however , If replaced generator, Just You can return one number at a time , Go back and forth many times

function* fib(max) {
var
t,
a = 0,
b = 1,
n = 0;
while (n < max) {
yield a;
[a, b] = [b, a + b];
n ++;
}
return;
}
 Copy code 

Try calling directly :

fib(5); // fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window}
 Copy code 

Call one directly generator Unlike calling a function ,fib(5) Just created a generator object , This object can be thought of as an array of hidden results , We need to go over and over again Trigger it , It's going to be in order, time after time Come up to Array elements

var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: false}
f.next(); // {value: undefined, done: true}
f.next(); // {value: undefined, done: true}
 Copy code 

next() Method will execute generator Code for , then , Every encounter yield x; Just return an object {value: x, done: true/false}, then “ Pause ”【 So it's better to get the second order of Fibonacci sequence than to execute the ordinary function every time n Items perform much better 】

Or use it directly for ... of Loop iteration generator object , This way we don't have to go every time next() And judgment done:

for (var x of fib(5)) {
console.log(x); // Output... In sequence 0, 1, 1, 2, 3
}
 Copy code 
  • Solve callback hell :( The top one How many districts does a prefecture level city have Example )
ajax('url_1', data1, function (err, result) {
if (err) {
return handle(err);
}
ajax('url_2', data2, function (err, result) {
if (err) {
return handle(err);
}
ajax('url_3', data3, function (err, result) {
if (err) {
return handle(err);
}
return success(result);
});
});
});
 Copy code 

With generator, use AJAX It can be written like this :

try {
r1 = yield ajax('url_1', data1);
r2 = yield ajax('url_2', data2); // have access to ajax('first') Result , That is to say r1
r3 = yield ajax('url_3', data3); // have access to ajax('second') Result , That is to say r2
success(r3);
}
catch (err) {
handle(err);
}
 Copy code 

Use here try...catch... sentence , So in try{ } There's no need to check the results in the region r1、r2、r3 Error handling , If something goes wrong, it will be catch Statement captures , And output error parameters err

  • A more advanced application is in Lazy-loading

( Hang in the air )

Generator

Generator Implementation principle of

Generator Implementation principle of : My simple understanding of how it works is , It's a bit like saving the result of a function to an object ( Array ) Inside , Then return , And then we're looking at this object ( Array ) One by one , Get the results we want every time . But the difference is : Use Generator Instead of functions It's not a waste of space , Because it's execution Generator.next() When To run Generator function

Yield

Generator The way the code is handled inside the function is :

  • The first time is from Function starting point To first yield sentence ;
  • The last time was from the last one yield sentence To The end of the function or return;
  • The rest of the time comes from yield sentence Execute to next yield sentence Then stop .

So it's like dividing a function into many, many sub block functions , The starting point of every subfunction is yield sentence , The end is next yield sentence ( Except for the first and last piece ), Nature can play a role in “ Pause ” The effect of 【 So as to achieve “ Synchronous blocking ” The effect of 】, And the return value of each small function will have a value called “ iterator ” In the container of

Final ,Generator The function returns an iterator at the end of execution

Generator.next() —— Iterator pattern

Definition : The iterator pattern refers to providing a way to access elements in an aggregate object sequentially , Without exposing the internal representation of the object

The simple understanding is : stay Don't expose In the case of internal representation of objects , can Traverse All the elements Now let's implement a simple iterator :

// No deep copy content is selected when data is acquired ,
// There are problems with handling reference types 
// Here's just a little simplification of the demonstration 
function Iterdtor(arr){
let data = [];
if(!Array.isArray(arr)){
data = [arr];
}else{
data = arr;
}
let length = data.length;
let index = 0;
// The core of iterators next
// When calling next Will start to output the next item of the internal object 
this.next = function(){
let result = {};
result.value = data[index];
result.done = (index === length - 1 ? true : false;)
if(index !== length){
index++;
return result;
}
// Returns a string prompt when the content is no longer available 
return 'data is all done'
};
}
let arr = [1,2,3,4];
// Generate an iterator object .
let iterdtor = new Iterdtor(arr);
 Copy code 

Console output :

image.png

async and await

async The function is Generator Functional Grammatical sugar . Use async Keyword substitution Generator Asterisk of function *,await Keyword substitution yield

Compare with Generator function ,async Function improves on the following four points :

  • Built in actuator Generator Function execution must depend on the actuator , That's why co modular , and async Function with actuator .
  • better semantics async and await, Compared with * and yield, The meaning is clearer .async Indicates that there is an asynchronous operation in the function ,await Indicates that the following expression needs to wait for the result .
  • Wider applicability co Module conventions ,yield The order can only be followed by Thunk function or Promise object , and async Functional await Command behind , It can be Promise object and Value of original type .
  • Return value async The return value of the function is Promise object , This is more than Generator The return value of the function is Iterator object It's much more convenient . you It can be used then Method Specify what to do next .

async and await Use

  • Ordinary functions use function Keyword start
  • async The function uses async function Keyword start
  • await Namely wait for The completion of the latter one , If the latter item is not completed, it will never go down

The top one How many districts does a prefecture level city have Example :

ajax('url_1',data1);
ajax('url_2',data2); // You need to get it before you can execute it ajax('url_1',data1) Result 
ajax('url_3',data3); // You need to get it before you can execute it ajax('url_2',data2) Result 
 Copy code 

Use async / await:

function fn(url,data) {
return new Promise((resolve, reject) => {
ajax(url, data, function (err, res) {
if (err) reject(err)
resolve(res)
})
})
}
async function asyncFn() {
let p1 = await fn('url_1',data1)
let p2 = await fn('url_2',data2)
let p3 = await fn('url_3',data3)
return p3
}
asyncFn().then(result => {
console.log(result)
}).catch(error => {
console.log(error)
})
 Copy code 

matters needing attention

  1. Always add in front of async Function of After implementation, they will Automatically returns a Promise object
  2. await must stay async The function uses , Not to be used alone
  3. await If it's followed by Promise object , Then it will wait for the execution of the function in the object to complete ; If it's with No Promise Object executes the following code / Equal to the following value
// await And then Promise object 
let promiseDemo = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('success')
console.log(3)
},0)
})
async function test() {
let result = await promiseDemo // 3
return result
}
// await Not in the back Promise object 
let promiseDemo = fn(() => {
console.log(3)
})
async function test() {
let result = await promiseDemo // 3
return result
}
 Copy code 

async and await Execution order of

This question follows async / await It's about the application of , And also JavaScript series -- event loop Event polling of

console.log(1) // 1
let promiseDemo = new Promise((resolve, reject) => {
console.log(2) // 1 2
setTimeout(() => {
let random = Math.random()
if (random >= 0) {
resolve('success')
console.log(3) // 1 2 4 6 3
} else {
reject('failed')
console.log(3)
}
}, 1000)
})
async function test() {
console.log(4) // 1 2 4
let result = await promiseDemo // Note that there are no parentheses here , It's execution new Promise(...) An object returned after 
return result
}
test().then(result => {
console.log(5) // 1 2 4 6 3 5
}).catch((result) => {
console.log(5)
})
console.log(6) // 1 2 4 6
 Copy code 

It is worth noting that :

  • We're at the beginning new Promise It has been implemented since the beginning of the year Promise Inside the arrow function code
  • and async function test() Only in test().then().catch() When it is called ,test() The code in the function starts to be executed

analysis :

  • 1 2 4 6 It's a synchronization task , It's up to the main thread , So in the first half of the output
  • Get into async function test() In the back of the execution to await promiseDemo sentence , Will wait for the timer to finish , Output 3
  • And then it will return to a Promise Object and assign it to a variable result,async Function and put this Promise Object is returned outside the function
  • The function is for this Promise Object use then() Methods and catch() Method , So as to output 5

Reference article

版权声明
本文为[ALKAOUA]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/05/20210503181828345s.html

  1. 浅谈 React 中的 XSS 攻击
  2. XSS attack in react
  3. 自学前端教程整理,附不容错过的前端100篇文章合集
  4. Self taught front-end tutorial collation, with a collection of 100 front-end articles that can not be missed
  5. 使用OpenTracing跟踪Go中的HTTP请求延迟
  6. Using opentracing to track HTTP request latency in go
  7. Encapsulating databinding allows you to write less than 10000 lines of code
  8. 03-HTML5标签-HTML5极速入门
  9. 03-html5 tag-html5 quick start
  10. LayUI - 极易上手拿来即用的前端 UI 框架
  11. Layui - easy to use front end UI framework
  12. Interpretation of lodash source code (1)
  13. Why is the first parameter of node family callback error?
  14. 报告:JavaScript 开发者达1380 万,C#超越 PHP,Rust 增长最快
  15. Report: Javascript developers reach 13.8 million, C surpasses PHP, and rust grows fastest
  16. 小白前端入门笔记(10),怎么设置网站内部的超链接?
  17. How to set up hyperlinks inside the website?
  18. Using node and socket to realize online chat room
  19. The core competitiveness of Vue: data bidirectional binding
  20. React configuration agent
  21. CSS layout
  22. Application scenario explanation of Vue dynamic component
  23. Redux learning notes 04 -- using multiple reducers to manage data
  24. After three months of typescript writing, what have I learned?
  25. Node family - what is a callback?
  26. React -- a simple implementation of render & create element
  27. JS learning simple usage of jquery
  28. Seamless love
  29. 小白前端入门笔记(12),设置哑链接
  30. Small white front-end entry notes (12), set dumb links
  31. Vue2. X opens composition API and TSX
  32. Interview record and thinking of social recruitment for one and a half years (Alibaba, Tencent, baidu offer)
  33. Flex learning notes
  34. The most essential closure article in the eastern hemisphere
  35. 2021-05-03 hot news
  36. Sword finger offer -- reverse order pair in array (JS Implementation)
  37. Working process of scaffold
  38. Use decorator mode to strengthen your fetch
  39. [JS] scope (Introduction)
  40. Employment information statistics network (interface document)
  41. Analysis of MVC
  42. [middle stage] please stay and join me in the backstage
  43. Understanding front end garbage collection
  44. [continuous update] front end special style implementation
  45. Flutter product analysis and package reduction scheme
  46. XPath positioning
  47. 前端开发css中的flex布局的使用
  48. The use of flex layout in front end development CSS
  49. JQuery核心函数和静态方法
  50. JQuery core functions and static methods
  51. Node family - understanding of blocking and non blocking
  52. 热点微前端Microfrontend的讨论:谷歌AdWords是真实的微前端
  53. Vue source code analysis (2) initproxy initialization proxy
  54. What's TM called react diff
  55. Summary of common front end data structure
  56. Useeffect in hooks
  57. [encapsulation 02 design pattern] Command pattern, share meta pattern, combination pattern, proxy pattern, strategy pattern
  58. Front end notes: virtual Dom and diff of vue2. X
  59. The best code scanning plug-in of flutter
  60. The simplest plug-in for rights management of flutter