当前位置:网站首页>Asynchronous development process - touch your hand and lead you to realize a promise
Asynchronous development process - touch your hand and lead you to realize a promise
2022-07-04 04:23:00 【Careteen】
Length is longer than the , But the key points are as follows , You can go directly to the topic of interest , each takes what he needs .
- Callback function
- analysis lodash Of after function
- analysis Node Read the file
- Why use promise
- Touch your hand and give you a hand promise
- Explain step by step from zero to one to achieve one promise
- Interview often takes an examination of , Please also read with questions .
- promise The relationship between the three states of ?
- How to achieve promise Chain call of ?
- How to judge and solve promise The problem of circular quotation ?
- How to achieve promise Of finally Method ?
- How to achieve promise Of all Method ?
- generator usage
- async-await
All the examples involved are stored in Warehouse , Interested students can directly clone Run locally .
This article mainly discusses the past and present life of asynchrony , And touch and take you to achieve a promise
because JavaScript Single thread features , We need asynchronous programming to solve the blocking problem .
Asynchronous programming problems
We may use the following functions to do some asynchronous operations in our daily work
- setTimeout
- onClick
- ajax
How to solve the asynchronous problem
The existing ways to solve the asynchronous problem are as follows
- Callback function
- promise
- generator nausea
- aync+await
Next, we will introduce various ways to solve the asynchronous problem one by one
Callback function
First, let's introduce higher-order functions , That is, the parameter of a function is a function or the return value of a function is a function , This function is called a higher-order function .
lodash-after function
Let's take another example , Regular use lodash Students should be familiar with a method _.after(n, fn), Role is fn Function is calling n It will be executed after times .
let fn = after(3, () => {
console.log(' Time to execute ')
})
fn()
fn()
fn() // => Time to execute How to achieve a after Function? , In fact, it's mainly the use of Closures and counts Thought :
const after = (times = 1, cb = _defaultCb) => {
return function () {
if (--times === 0) {
cb()
}
}
}
const _defaultCb = () => {} among cb Pass in... As a function parameter after function , It is an application of higher-order function .
after Function example address
Node Read the file
Now there's a scene , Read the contents of two files , Assign to an object , And print .
stay ./static Two new files are created under name.txt,age.txt, Expect to read the contents of the file and assign it to an object , And then print .
const fs = require('fs')
let schoolInfo = {}
fs.readFile('./static/name.txt', 'utf8', (err,data) => {
schoolInfo['name'] = data
})
fs.readFile('./static/age.txt', 'utf8', (err, data) => {
schoolInfo['age'] = data
})
console.log(schoolInfo) // {}Because the process of reading files is asynchronous , Therefore, it is impossible to meet expectations in this way .
And asynchronous operation has the following three problems
- 1、 Asynchronous cannot catch errors
- 2、 Asynchronous programming , There may be a callback hell
- 3、 Multiple asynchronous operations , At the same time , How to synchronize asynchronous results ?
Everyone should be familiar with callback hell .
const fs = require('fs')
let schoolInfo = {}
fs.readFile('./static/name.txt', 'utf8', (err,data) => {
schoolInfo['name'] = data
fs.readFile('./static/age.txt', 'utf8', (err, data) => {
schoolInfo['age'] = data
})
})And the reading time of the two files is cumulative , Not in parallel , If the files are many and large , The waiting time will be very long , So... Is not recommended .
Here is the third question Multiple asynchronous operations , At the same time , How to synchronize asynchronous results ?, May adopt Publish subscribe How to solve
// A simple way to subscribe to objects
let dep = {
arr: [],
emit () {
this.arr.forEach((fn) => {
fn()
})
},
on (fn) {
this.arr.push(fn)
}
}If you don't know the publish subscribe mode, please move to mine Another blog
The following operations can achieve the expectation
let schoolInfo = {}
const fs = require('fs')
// A simple way to subscribe to objects
let dep = {
arr: [],
emit () {
this.arr.forEach((fn) => {
fn()
})
},
on (fn) {
this.arr.push(fn)
}
}
// subscribe
dep.on(() => {
// �� Only after reading the contents of the two files and assigning values will it be printed
if (Object.keys(schoolInfo).length === 2){
console.log(schoolInfo)
}
})
// Read trigger
fs.readFile('./static/name.txt', 'utf8', (err, data) => {
schoolInfo['name'] = data
dep.emit()
})
fs.readFile('./static/age.txt', 'utf8', (err, data) => {
schoolInfo['age'] = data
dep.emit()
})The print event is triggered every time the file is read , Judge in the event, and print only when both reads are completed .
The above method seems to solve the third problem mentioned above Multiple asynchronous operations , At the same time , The result of synchronous and asynchronous , But as demand changes , You need to read another address file , The following changes are required :
...
// subscribe
dep.on(() => {
// �� Only after reading the contents of the two files and assigning values will it be printed
if (Object.keys(schoolInfo).length === 3){ // 2 Change it to 3
console.log(schoolInfo)
}
})
...
// Add a new item adress
fs.readFile('./static/adress.txt', 'utf8', (err, data) => {
schoolInfo['adress'] = data
dep.emit()
})Add more items , The extensibility of the code is very poor .
How to implement a promise Then solve the problems mentioned above
node Read the file code address
Why use promise
Now, let's introduce promise The problem solved by the emergence of
- Back to hell , If multiple asynchronous requests , There is a joint and several relationship , Callback nesting
- If multiple asynchronous implementations are concurrent , There will be returned results that cannot be synchronized or asynchronously
- Error handling is inconvenient
promise usage
- Don't talk to you BB
Touch your hand and give you a hand promise
First of all, I need to mention promise/A+ standard , We wrote it ourselves promise It needs a standard . You can follow this standard step by step .
Three states are required
const PENDING = 'pending' // Waiting state const FULFILLED = 'fulfilled' // Success state const REJECTED = 'rejected' // Failure state
- When the state of
pendingwhen- May be converted to
fulfilledorrejected
- May be converted to
- When the state of
fulfilledorrejectedwhen- Cannot change to other state
- There has to be one
valueorreasonAnd it can't be changed
Interview point :promise The relationship between the three states of ?
then Method
For more details, please move to the document , Here are some key points
- Handle
executorAbnormal code in function - Handle
executorThe code in the function is asynchronous - Handle then Multiple calls to
- Handle then Chain call of
Handle executor Abnormal code in function
Yes executortry-catch that will do
class Promise {
constructor(executor) {
let self = this
self.status = PENDING
self.value = undefined
self.reason = undefined
const resolve = (value) => {
if(self.status === PENDING){
self.value = value
self.status = FULFILLED
}
}
const reject = (reason) => {
if(self.status === PENDING){
self.reason = reason
self.status = REJECTED
}
}
try{
executor(resolve, reject) // If you do this executor An exception is thrown during execution We should go next then The failure of the
}catch(e){
reject(e)// Something went wrong reason It's a mistake
}
}
then (onFulfilled, onRejected) {
if (this.status === FULFILLED){
onFulfilled(this.value)
}
if (this.status === REJECTED){
onRejected(this.reason)
}
}
}Use the following
let Promise = require('./3.1.promise.js')
let p = new Promise((resolve,reject) => {
resolve('xx')
})
p.then((data) => {
console.log('p success',data)
}, (err) => {
console.log(err)
})
// => p success xxSimple version of 1.0.0 Address as well as Test case address
Although a very simple promise, But there are still many problems , For example, below
let Promise = require('./3.1.promise.js')
let p2 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('xxx')
}, 1000)
})
p2.then((data) => {
console.log('p2 success',data)
}, (err) => {
console.log(err)
})
// => p success xx
// p second success xxAsynchronous code will not be processed
Handle executor The code in the function is asynchronous
Use the idea of publish subscribe mode to deal with
class Promise {
constructor(executor) {
let self = this
self.status = PENDING
self.value = undefined
self.reason = undefined
self.onResolvedCallbacks = [] // newly added An array is stored and processed successfully
self.onRejectedCallbacks = [] // newly added Failed to store an array
const resolve = (value) => {
if(self.status === PENDING){
self.value = value
self.status = FULFILLED
self.onResolvedCallbacks.forEach((fn) => { // newly added When triggered, traverse all
fn()
})
}
}
const reject = (reason) => {
if(self.status === PENDING){
self.reason = reason
self.status = REJECTED
self.onRejectedCallbacks.forEach((fn) => { // newly added When triggered, traverse all
fn()
})
}
}
try{
executor(resolve, reject) // If you do this executor An exception is thrown during execution We should go next then The failure of the
}catch(e){
reject(e)// Something went wrong reason It's a mistake
}
}
then (onFulfilled, onRejected) {
if (this.status === FULFILLED){
onFulfilled(this.value)
}
if (this.status === REJECTED){
onRejected(this.reason)
}
if( this.status === PENDING){ // newly added Deal with asynchronous
// Default current new Promise executor There is asynchronous in
this.onResolvedCallbacks.push(() => {
onFulfilled(this.value)
});
this.onRejectedCallbacks.push(() => {
onRejected(this.reason)
})
}
}
}Use
let Promise = require('./3.2.promise.js')
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('xxx')
}, 1000)
})
p.then((data) => {
console.log('p success',data)
}, (err) => {
console.log(err)
})
p.then((data) => {
console.log('p second success',data)
}, (err) => {
console.log(err)
})
// Print in a second
// => p success xxx
// p second success xxxSimple version of 1.0.1 Address as well as Test case address
Handle then Chain call of
and jQuery Chain call a routine , But here we need to return a new promise Not the present , Because the successful state and the failed state cannot be changed to other States
class Promise {
constructor(executor) {
let self = this
self.status = PENDING
self.value = undefined
self.reason = undefined
self.onResolvedCallbacks = []
self.onRejectedCallbacks = []
const resolve = (value) => {
if(self.status === PENDING){
self.value = value
self.status = FULFILLED
self.onResolvedCallbacks.forEach((fn) => {
fn()
})
}
}
const reject = (reason) => {
if(self.status === PENDING){
self.reason = reason
self.status = REJECTED
self.onRejectedCallbacks.forEach((fn) => {
fn()
})
}
}
try{
executor(resolve, reject) // If you do this executor An exception is thrown during execution We should go next then The failure of the
}catch(e){
reject(e)// Something went wrong reason It's a mistake
}
}
then (onFulfilled, onRejected) {
let self = this
let promise2 // This promise2 Every time we call then After returning to the new promise
// This is the main way to realize chain call promise
promise2 = new Promise((resolve, reject) => {
if (self.status === FULFILLED) {
setTimeout(() => {
try {
// This return value is the execution result of the successful function
let x = onFulfilled(self.value)
// Judge promise2 and x It's also then The result returned by the function is the same as promise2 The relationship between If x It's a normal value Then let's promise2 success If Is a failure promise Then let's promise2 Failure
self._resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
}
if (self.status === REJECTED) {
setTimeout(() => {
try {
// This return value is the execution result of the failed function
let x = onRejected(self.reason)
// Judge promise2 and x It's also then The result returned by the function is the same as promise2 The relationship between If x It's a normal value Then let's promise2 success If Is a failure promise Then let's promise2 Failure
self._resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
}
if (self.status === PENDING) {
// Default current new Promise executor There is asynchronous in
self.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(self.value)
self._resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
});
self.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(self.reason)
self._resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
// Internal core method Handle The return value of successful or failed execution and promise2 The relationship between
_resolvePromise (promise2, x, resolve, reject) {
// This handler The logic that needs to be handled in Korean is very complex
// It's possible that this x It's a promise But this promise It's not my own
resolve(x) // At present, there is only one simple treatment
}
}Use
let Promise = require('./3.3.promise.js')
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('xxx')
}, 1000)
})
// promise in Every time you call then Should return a new promise
// promise Instances of can only succeed or fail You can't succeed and fail
p.then((data) => {
console.log('p success', data)
}, (err) => {
console.log(err)
}).then((data) => {
console.log('success then', data)
}, (err) => {
console.log(err)
})
// Print in a second
// => p success xxx
// success then undefinedSimple version of 1.0.2 Address as well as Test case address
Interview point : How to achieve promise Chain call of ?
For example, the code is only simple _resolvePromise Method
perfect _resolvePromise
Step by step to standardize the document Handle _resolvePromise
The following situations need to be considered
_resolvePromise (promise2, x, resolve, reject)
- x Is a normal value
- x by promise2 Will cause a loop call
- x For an object or function
- x For one promise
Consider the above to improve
// Internal core method Handle The return value of successful or failed execution and promise2 The relationship between
_resolvePromise (promise2, x, resolve, reject) {
// This handler The logic that needs to be handled in Korean is very complex
// It's possible that this x It's a promise But this promise It's not my own
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise '))
}
// You don't just need to think about yourself Also need to consider It may be someone else's promise
let called // Document requirements Once it's done Cannot call failed
if ((x !== null && typeof x === 'object') || typeof x === 'function') {
// This can only be said x It could be a promise
try {
// x = {then:function(){}}
let then = x.then // take then Method
if (typeof then === 'function') {
then.call(x, y => { // resolve(new Promise)
if (called) return
called = true
resolvePromise(promise2, y, resolve, reject) // Recursive check promise
}, reason => {
if (called) return
called = true
reject(reason)
})
} else { // then Method does not exist
resolve(x); // Common value
}
} catch (e) { // If you take then Method error , Just go and fail
if (called) return
called = true
reject(e)
}
} else { // Common value
resolve(x)
}
}Use
let Promise = require('./3.4.promise.js')
// Normal return value
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('xxx')
}, 1000)
})
p.then((data) => {
console.log(`p success ${data}`)
return 'first result'
}, (err) => {
console.log(err)
}).then((data) => {
console.log(`p success then ${data}`)
}, (err) => {
console.log(`p error ${err}`)
})
// Print in a second
// => p success xxx
// p success then first result
// Throw the wrong
let p2 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('p2 xxx')
}, 1000)
})
p2.then((data) => {
throw new Error('just happy')
}, (err) => {
console.log(err)
}).then((data) => {
console.log(`p2 success then ${data}`)
}, (err) => {
console.log(`p2 error ${err}`)
})
// Print in a second
// => p2 error Error: just happy
// promise
let p3 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('p3 xxx')
}, 1000)
})
p3.then((data) => {
return new Promise((resolve, reject) => {
resolve('p3 data')
}).then(data => {
return data
})
}, (err) => {
console.log(err)
}).then((data) => {
console.log(`p3 success then ${data}`)
}, (err) => {
console.log(`p3 error ${err}`)
})
// Circular reference - Examples to be changed
let p4 = new Promise((resolve,reject) => {
let circleP = new Promise((resolve, reject) => {
resolve(circleP)
})
return circleP
})
p4.then((data) => {
console.log(data)
})Simple version of 1.0.3 Address as well as Test case address
Interview point : How to judge and solve promise The problem of circular quotation ?
The above one conforms to Promise/A+ canonical promise Basically completed
How to verify what you wrote promise Is it right ?
Add the following deferred Methods for inspection
// be based on Promise Realization Deferred Also available to `promises-aplus-tests` Checking
static deferred () {
let dfd = {}
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve
dfd.reject = reject
})
return dfd
} Install inspection tools promises-aplus-tests
npm i -g promises-aplus-tests
Execution check
promises-aplus-tests your-promise.js
All of them are green, which means they have passed the inspection
promise periphery
The above is just a simple promise, We expect to improve more functions :
- catch Method
- Static methods
- finally Method
- all Method
- race Method
The address of the following implementation is Simple version of 1.1.1 as well as The test case
catch Method
Realization
// be used for promise Method chain Capture the front onFulfilled/onRejected Exception thrown
catch (onRejected) {
return this.then(null, onRejected)
}Use
let Promise = require('./3.6.promise.js')
// catch
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('xxx')
}, 1000)
})
p.then((data) => {
console.log(`p success then ${data}`)
}).then((data) => {
throw new Error('just happy')
}).catch(err => {
console.log(`p ${err}`)
})
// => p success then xxx
// p Error: just happyStatic methods
Realization
static resolve (value) {
return new Promise(resolve => {
resolve(value)
})
}
static reject (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}Use
let Promise = require('./3.6.promise.js')
// static resolve reject
let p2 = Promise.resolve(100)
p2.then(data => {
console.log(`p2 ${data}`)
})
let p3 = Promise.reject(999)
p3.then(data => {
console.log(`p3 ${data}`)
}).catch(err => {
console.log(`p3 err ${err}`)
})
// => p2 100
// p3 err 999finally Method
Realization
// finally It's also then A shorthand for
finally (cb) {
// Success or failure To perform all cb And pass the value of success or failure down
return this.then(data => {
cb()
return data
}, err => {
cb()
throw err
})
}Use
let Promise = require('./3.6.promise.js')
// finally
let p4 = Promise.resolve(100)
p4.then(data => {
throw new Error('error p4')
}).finally(data => {
console.log(`p4 ahhh`)
}).catch(err => {
console.log(`p4 err ${err}`)
})
// => p4 ahhh
// p4 err Error: error p4Interview point : How to achieve promise Of finally Method ?
all Method
Realization
/**
* @desc When everything in this array promise Objects all become resolve In state , Will resolve.
* @param {Array<Promise>} promises promise An array of objects as parameters
* @return Return to one Promise example
*/
static all (promises) {
return new Promise((resolve, reject) => {
let arr = []
// The way data is processed
let i = 0
const processData = (index, data) => {
arr[index] = data // The relationship between the index and length of the array
if (++i === promises.length){ // When the length of the array and promise When the number of is equal Account for all promise It's all done
resolve(arr)
}
}
for (let i = 0; i < promises.length; i++){
let promise = promises[i]
if (typeof promise.then == 'function'){
promise.then(function (data) {
processData(i, data) // Index and data correspond Easy to use
}, reject)
}else{
processData(i,promise)
}
}
})
}Use
let Promise = require('./3.6.promise.js')
// all & race
const fs = require('fs')
const path = require('path')
const resolvePath = (file) => {
return path.resolve(__dirname, '../callback/static/', file)
}
const read = (file) => {
return new Promise((resolve, reject) => {
fs.readFile(resolvePath(file), 'utf8', (err, data) => {
if(err) reject(err)
resolve(data)
})
})
}
// all
Promise.all([
read('name.txt'),
read('age.txt')
]).then(data => {
console.log(`all ${data}`)
}).catch(err => {
console.log(`all err ${err}`)
})
// => all Careteen,23Interview point : How to achieve promise Of all Method ?
race Method
Realization
/**
* @desc As long as there is one promise Objects enter FulFilled perhaps Rejected In terms of state , It will continue to be processed later ( It depends on which is faster )
* @param {Array<Promise>} promises receive promise An array of objects as parameters
* @return Return to one Promise example
*/
static race (promises) {
return new Promise((resolve, reject) => {
promises.forEach((promise, index) => {
promise.then(resolve, reject)
})
})
}Use
let Promise = require('./3.6.promise.js')
// all & race
const fs = require('fs')
const path = require('path')
const resolvePath = (file) => {
return path.resolve(__dirname, '../callback/static/', file)
}
const read = (file) => {
return new Promise((resolve, reject) => {
fs.readFile(resolvePath(file), 'utf8', (err, data) => {
if(err) reject(err)
resolve(data)
})
})
}
// race
Promise.race([
read('name.txt'),
read('age.txt')
]).then(data => {
console.log(`race ${data}`)
}).catch(err => {
console.log(`race err ${err}`)
})
// => race Careteen/23 not always It depends on the reading speed generator usage
Understanding generator Let's look at an example first .
Realize an addition function that can pass any parameter
The sum function can be obtained by dividing five by two
const sum = () => {
return [...arguments].reduce((ret, item) => {
return ret + item
}, 0)
}
sum(1, 2, 3, 4) // => 10
sum(1, 2, 3, 4, 5) // => 15 Use ES6 The expansion operator of ... All parameters can be listed , Then wrap it in an array , You can convert an array of classes into an array . utilize reduce To achieve accumulation , To get the summation function .
Can the expansion operator manipulate the class array pretended by the object ? Let's have a try
let obj = {
0: 1,
1: 2,
2: 3,
length: 3
}
console.log([...obj]) // => TypeError: obj[Symbol.iterator] is not a functionWe can know that objects cannot be iterated , According to the error information , Let's improve the code
let o = { 0: 1, 1: 2, 2: 3, length: 3, [Symbol.iterator]: function () {
let currentIndex = 0
let that = this
return {
next(){
return {
value: that[currentIndex++],
done: currentIndex-1 === that.length
}
}
}
}}
let arr = [...o] // [1, 2, 3]Reuse generator Realization
let o = {0: 1, 1: 2, 2: 3, length: 3, [Symbol.iterator]: function* () {
let index = 0
while (index !== this.length) {
yield this[index]
index++
}
}
}
let arr = [...o] // [1, 2, 3]Generator can realize generation iterator , Generator function is to add a * Combined with yield To use , also yield It has pause function .
function * say() {
yield 'node'
yield 'react'
yield 'vue'
}How to traverse iterators ?
let it = say ()
let flag = false
do{
let {value, done} = it.next()
console.log(value)
flag = done
}while(!flag)
// => node
// react
// vue
// undefined Iterators provide next Method , Iterative value And whether the iteration has been completed done, You can traverse with one loop .
yield The use scenario of the return value of
function * say() {
let a = yield 'hello'
console.log('a', a)
let b = yield 'careteen'
console.log('b', b)
let c = yield 'lanlan'
console.log(c)
}
let it = say()
it.next(100) // for the first time next Pass parameters It's meaningless
it.next(200)
it.next(300)
// => a 200
// b 300generator The execution process is generally shown in the figure below
You can see for the first time next Passing parameters is meaningless , So the output is a 200 b 300
All of the above are synchronous , So let's see yield The following is the asynchronous scenario .
Let's take another example to further understand .
By reading the file 1.txt The content is 2.txt, Read again 2.txt The content is 3.txt, Last read 3.txt The content in Careteen
First, you need to prepare three files , Put in ./static Under the table of contents , Then prepare the function to read the file ,
const fs = require('fs')
const path = require('path')
const resolvePath = (file) => {
return path.resolve(__dirname, './static/', file)
}
function read (file) {
return new Promise((resolve, reject) => {
fs.readFile(resolvePath(file), 'utf8', (err, data) => {
if (err) reject(err)
resolve(data)
})
})
}In the use of generator Implement the read function
function * r() {
let r1 = yield read('1.txt')
let r2 = yield read(r1)
let r3 = yield read(r2)
return r3
} The desired process is by reading the file 1.txt The content is 2.txt, Read again 2.txt The content is 3.txt, Last read 3.txt The content in Careteen, Go back .
First of all, we can think of using callback to solve , because yield There's a promise
let it = r()
let {value,done} = it.next()
value.then((data) => { // data->2.txt
let {value,done} = it.next(data)
value.then((data) => {
let { value, done } = it.next(data)
value.then((data) => {
console.log(data) // data-> result
})
})
})
// => CareteenBut this will create a callback hell , So we need to optimize , We need an iterative function , Recursion can achieve
function co (it) {
return new Promise((resolve, reject) => {
// next Method express koa principle It's all like this
function next (data) { // Use iterative functions to implement Asynchronous operations are performed sequentially
let { value, done } = it.next(data)
if(done){
resolve(value)
}else{
value.then((data) => {
next(data)
},reject)
}
}
next()
})
}So that asynchrony can be executed in sequence , Finally, let's take a look at the implementation
co(r()).then((data) => {
console.log(data)
})
// => Careteen It is perfectly realized , But if yield After is a synchronization operation , No, then Method , stay co We also need special treatment in the method , It's easier .
Fucking great TJ The great god CO The library handles this perfectly , Interested can go to the warehouse to see the source code , Only 200 Multiple lines .
generator Application :
How to achieve generator
function * careteen() {
yield 100
yield 200
}You can see babel Compiled results
async-await
- It's synchronous , Grammar sugar is sweet but not greasy .
- bluebird
- promisify
- promisifyAll
- async-await
- Serial condition
- Parallel situation
- async-await Internal mechanism
- stay babel Compile results in , In essence generator+co
- Example
- Three small balls roll
- Callback implementation Back to hell
- promise Realization It's not very beautiful either
- generator Realization need co library
- async-await Realization
- Three small balls roll
async function careteen() {
await 100
await 200
return 300
}
careteen.then(_ => {
console.log(_)
}) adopt babel After compiling It can be seen that it is essentially through generator+co The way to achieve .
边栏推荐
- Flink学习7:应用程序结构
- 【微服务|openfeign】feign的两种降级方式|Fallback|FallbackFactory
- [webrtc] M98 Ninja build and compile instructions
- Unity资源路径
- PPt 教程,如何在 PowerPoint 中将演示文稿另存为 PDF 文件?
- Katalon使用script实现查询List大小
- 仿《游戏鸟》源码 手游发号评测开服开测合集专区游戏下载网站模板
- vim正确加区间注释
- [book club issue 13] multimedia processing tool ffmpeg tool set
- 精品网址导航主题整站源码 wordpress模板 自适应手机端
猜你喜欢
![[microservice openfeign] @feignclient detailed explanation](/img/8d/83bcde1355366c7c88a7a9ade7f9eb.png)
[microservice openfeign] @feignclient detailed explanation

Idea configuration 360zip open by default -- external tools
![[Logitech] m720](/img/bb/44144a1c3907808398c05b3b36962c.png)
[Logitech] m720

Distributed system: what, why, how

Flink learning 8: data consistency

Storage of MySQL database

Exercises in quantum mechanics

架构训练毕业设计+总结

Leetcode skimming: binary tree 07 (maximum depth of binary tree)

微信公众号无限回调授权系统源码
随机推荐
三年进账35.31亿,这个江西老表要IPO了
The difference between bagging and boosting in machine learning
VIM mapping command
Flink学习8:数据的一致性
JS realizes the effect of text scrolling marquee
2021 RSC | Drug–target affinity prediction using graph neural network and contact maps
C语言单向链表练习
Cesiumjs 2022^ source code interpretation [0] - article directory and source code engineering structure
Flink学习7:应用程序结构
Pointer array and array pointer
Configuration and hot update of nocturnal simulator in hbuildx
Pytest multi process / multi thread execution test case
PostgreSQL users cannot create table configurations by themselves
Rhcsa-- day one
Katalon uses script to query list size
Two sides of the evening: tell me about the bloom filter and cuckoo filter? Application scenario? I'm confused..
(pointeur) Écrivez - vous une fonction qui compare la taille de la chaîne et fonctionne comme strcmp.
Programmers' telecommuting is mixed | community essay solicitation
NFT新的契机,多媒体NFT聚合平台OKALEIDO即将上线
分布式系统:what、why、how