非同期処理の変遷史Promise、Generator、async/await
3985 ワード
Promiseが解決したい問題
非同期操作は非同期操作によって出現するコールバック地獄です.
ソス6時代は、Promiseに基づいて、Generatorを加えました.
ソス8時代は、Promiseに基づいて、async/awaitを加えました.
職務に服してデモを行う
非同期操作は非同期操作によって出現するコールバック地獄です.
1(function( 1){
2(function( 2){
3(function( 3){
4(function( 4){
5(function( 5){
6(function( 3){
...
})
})
})
})
})
})
Promiseを使った後new Promise( 1)
.then( 2( 1))
.then( 3( 2))
.then( 4( 3))
.then( 5( 4))
.then( 6( 5))
.catch( ( ))
まだ直観が足りないですソス6時代は、Promiseに基づいて、Generatorを加えました.
function *task() {
const 1 = yield 1
const 2 = yield 2( 1)
const 3 = yield 3( 2)
const 4 = yield 4( 3)
const 5 = yield 5( 4)
......
}
外部実行関数run(task)
Promise+Generatorconst request = require('axios')
const { sleep } = require('./tools')
request.defaults.baseURL = 'http://127.0.0.1:3000'
function * login () {
const {
data: { token },
} = yield request('/auth', { method: 'POST', data: { username: 'test', password: 'xxxxxxx' } })
console.log('1.token->', token)
yield sleep(2)
const { data: roles } = yield request('/roles', { params: { token } })
console.log('2.roles->', roles)
yield sleep(2)
const { data: menus } = yield request('/menus', { params: { roles } })
console.log('3.menus->', menus)
}
function run (g) {
const it = g() //
const each = res => {
if (!res.done && res.value instanceof Promise) {
res.value.then(v => {
each(it.next(v)) // yield yield
})
} else if (res.done) {
return
} else {
throw new Error('yield Promise ')
}
}
each(it.next())
}
run(login)
/**
* sleep
*/
exports.sleep = time => {
return new Promise(resolve => {
console.log(` ${time} ...`)
setTimeout(() => {
resolve(true)
}, time * 1000)
})
}
run関数はcoライブラリでも代用できます.npm install co
const run = require('co')
......
run(login)
まだちょっと面倒です.外部に実行関数があります.ソス8時代は、Promiseに基づいて、async/awaitを加えました.
async function task() {
const 1 = await 1
const 2 = await 2( 1)
const 3 = await 3( 2)
const 4 = await 4( 3)
const 5 = await 5( 4)
......
}
Promise+async/awaitconst request = require('axios')
request.defaults.baseURL = 'http://127.0.0.1:3000'
/**
* es8 async/await
*/
async function login () {
const {
data: { token },
} = await request('/auth', { method: 'POST', data: { username: 'test', password: 'xxxxxxx' } })
console.log('1.token->', token)
const { data: roles } = await request('/roles', { params: { token } })
console.log('2.roles->', roles)
const { data: menus } = await request('/menus', { params: { roles } })
console.log('3.menus->', menus)
}
login()
この関数を実行すればいいです.職務に服してデモを行う
const app = require('express')()
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(
bodyParser.urlencoded({
extended: true,
}),
)
app.post('/auth', (req, res) => {
const { username } = req.body
console.log(username)
res.send({
id: 1,
name: username,
age: 18,
token: `absfgsakjdhjskahdsklh`,
})
})
app.get('/roles', (req, res) => {
res.send([1, 2, 3])
})
app.get('/menus', (req, res) => {
res.send([
{ name: ' ', path: '/' },
{ name: ' ', path: '/users' },
])
})
app.listen(3000, () => {
console.log(`server run time: ${Date.now()}`)
})