异步同步化
ES6前
回调地狱
当出现请求之间相互依赖时,就往往出现这种回调地狱
,维护起来非常难受
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 $.ajax ( { url : 'https://ku.qingnian8.com/dataApi/news/navlist.php' , type : 'GET' , success : resp => { let id = resp[0 ].id $.ajax ( { url : 'https://ku.qingnian8.com/dataApi/news/newslist.php' , type : 'GET' , data : { cid : id }, success : resp => { let id = resp[0 ].id $.ajax ({ url : 'https://ku.qingnian8.com/dataApi/news/comment.php' , type : 'GET' , data : { aid : id }, success : resp => { console .log (resp) } }) } } ) } } )
封装回调
封装回调本质上和写在一起都是一样的, 只不过看起来比较清晰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 const getNav = (callback: (res: any ) => void ) => { $.ajax ({ url : 'https://ku.qingnian8.com/dataApi/news/navlist.php' , type : 'GET' , success : resp => { callback (resp) } }) }const getArticle = (callBack: (res: any ) => void , id: number ) => { $.ajax ({ url : 'https://ku.qingnian8.com/dataApi/news/newslist.php' , type : 'GET' , data : { cid : id }, success : resp => { callBack (resp) } }) }const getComment = (callBack: (res: any ) => void , id: number ) => { $.ajax ({ url : 'https://ku.qingnian8.com/dataApi/news/comment.php' , type : 'GET' , data : { aid : id }, success : resp => { callBack (resp) } }) }getNav ( res => { let id = res[0 ].id getArticle (res1 => { let id = res1[0 ].id getComment (res2 => { console .log (res2) }, id) }, id) } )
ES6后
Promise
promise是解决异步的方法,本质上是一个构造函数,可以用它实例化一个对象。对象身上有resolve、reject、all,原型上有then、catch方法。promise对象有三种状态:pending(初识状态/进行中)、resolved或fulfilled(成功)、rejected(失败)
pending。它的意思是 “待定的,将发生的”,相当于是一个初始状态。创建Promise对象时,且没有调用resolve或者是reject方法,相当于是初始状态。这个初始状态会随着你调用resolve,或者是reject函数而切换到另一种状态。
resolved。表示解决了,就是说这个承诺实现了。 要实现从pending到resolved的转变,需要在 创建Promise对象时,在函数体中调用了resolve方法。
rejected。拒绝,失败。表示这个承诺没有做到,失败了。要实现从pending到rejected的转换,只需要在创建Promise对象时,调用reject函数。
使用Promise包起来后,再链式调用,就很优雅了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 const getNav = (): Promise <any > => { return new Promise ((resolve, reject ) => { $.ajax ({ url : 'https://ku.qingnian8.com/dataApi/news/navlist.php' , type : 'GET' , success : resp => { resolve (resp) }, error : err => { reject (err) } }) }) }const getArticle = (id : number ): Promise <any > => { return new Promise ((resolve, reject ) => { $.ajax ({ url : 'https://ku.qingnian8.com/dataApi/news/newslist.php' , type : 'GET' , data : { cid : id }, success : resp => { resolve (resp) }, error : err => { reject (err) } }) }) }const getComment = (id : number ): Promise <any > => { return new Promise ((resolve, reject ) => { $.ajax ({ url : 'https://ku.qingnian8.com/dataApi/news/comment.php' , type : 'GET' , data : { aid : id }, success : resp => { resolve (resp) }, error : err => { reject (err) } }) }) }getNav ().then (res => { let id = res[0 ].id return getArticle (id) }).then (res => { return getComment (res[0 ].id ) }).then (res => { console .log (res) })
ES7
await / async ES7的新规范,异步处理同步化
这两个命令是成对出现的,如果使用await没有在函数中使用async命令,那就会报错,如果直接使用async没有使用await不会报错,只是返回的函数是个promise,可以,但是没有意义,所以这两个一起使用才会发挥出它们本身重要的作用。所谓异步同步化感觉就是将一些需要异步执行的任务放在一起让他们同步。
1 2 3 4 5 6 7 8 9 10 11 const onload = async ( ) => { let res, id res = await getNav () id = res[0 ].id res = await getArticle (id) id = res[0 ].id res = await getComment (id) console .log (res) }onload ()
使用axios请求时已经封装好了Promise,更方便
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const getNav = (): Promise <any > => { return get ('https://ku.qingnian8.com/dataApi/news/navlist.php' ) }const getArticle = (id : number ): Promise <any > => { return get ('https://ku.qingnian8.com/dataApi/news/newslist.php' , {cid : id}) }const getComment = (id : number ): Promise <any > => { return get ('https://ku.qingnian8.com/dataApi/news/comment.php' , {aid : id}) }const onload = async ( ) => { let res, id res = await getNav () id = res[0 ].id res = await getArticle (id) id = res[0 ].id res = await getComment (id) console .log (res) }onload ()
封装的axios
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import type {AxiosRequestConfig , Method } from 'axios' import axios from "axios" ;const service = axios.create ({ baseURL : 'https://ku.qingnian8.com' , timeout : 5000 }) service.interceptors .response .use (response => response.data )type Data <T> = { code : number message : string data : T }const request = <T>(url: string , method: Method, submitData?: object , config?: AxiosRequestConfig ) => { return service.request <T, Data <T>>({ url, method, [method.toLowerCase () === 'get' ? "params" : "data" ]: submitData, ...config }) }export const get = (url: string , submitData?: object , config?: AxiosRequestConfig ) => { return request (url, 'get' , submitData, config) }export const post = (url: string , submitData?: object , config?: AxiosRequestConfig ) => { return request (url, 'post' , submitData, config) }export default request