Promise 要解决的问题
异步操作依赖异步操作,从而出现的回调地狱
请求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(处理异常(异常信息))
还是不够直观
so es6 时代,基于 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 + Generator
const 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)
还是有些麻烦,还要外部有个执行函数才行
so es8 时代,基于 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/await
const 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()
执行该函数即可
服务端 demo
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()}`)
})