原贴链接:javascript异步之async(二)
这是javascript异步系列文章的第八篇
昨天讨论了javascript的Generator生成器
简单回顾
Generator生成器,区别于普通函数,它可以执行暂停操作,
而next就是驱动Generator的暂停和启动的“开关”
yield只能写在Generator内部,通过next启动生成器后,遇到yield就会暂停
yield和next之间可以相互传值
第一个next不需要传值,第一个next只是用来启动Generator
但是它可以接受第一个yield后面的值(前提是如果有值存在,否则就是undefined)
昨天的栗子🌰有点“hello world”,今天增加一点复杂度
一个需求
需求如下:
现在有接口1,接口2,接口3 按顺序输出接口1,接口2,接口3的请求值
我们还是使用Jquery处理ajax请求
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
还是easy-mock上面的那三个接口,为了拉长接口三的执行时间,我这接口了加入了长度为10-20 的数组 保证它比接口一和接口二慢
因为后面要对这三个接口的请求进行封装,先把代码列出来,方便查询参考
function loadData1() {$.ajax({url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1",success: ({data,success}) => {if (success) {console.log(data);}}});}function loadData2() {$.ajax({url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise2",success: ({data}) => {console.log(data);}});}function loadData3() {$.ajax({url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock",success: ({data,success}) => {if (success) {console.log(data);}}});}
回调函数
常规做法
即,loadData1执行成功后,执行loadData2,loadData2执行成功后执行loadData3
function getData() {$.ajax({url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1",success: ({data,success}) => {if (success) {console.log(data);$.ajax({url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise2",success: ({data}) => {console.log(data);if (data.name) {$.ajax({url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock",success: ({data,success}) => {if (success) {console.log(data);}}});}}});}}});}getData()
输出符合预期

回调地狱,说的就是你😂
Promise
来一个Promise实现的,顺便对前面的Promise进行复习
/**对ajax的请求做了一个简单的封装*@ajaxUrl,接口地址,公共部分已经抽取*@successCb,ajax请求成功后的回调函数*/function ajaxFun(ajaxUrl, successCb) {$.ajax({url: `https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/${ajaxUrl}`,success: res => successCb(res)});}//promisenew Promise((resolve, reject) => {ajaxFun("promise1", ({data,success}) => {if (success) {console.log('接口一', data);resolve(data)}})}).then(() => {ajaxFun("promise2", ({data}) => {if (data.name) {console.log('接口二', data);}})}).then(() => {ajaxFun("mock", ({data,success}) => {if (success) {console.log('接口三', data);}})})
Generator实现
function loadData1() {ajaxFun("promise1", ({data,success}) => {if (success) {console.log('接口一', data);it.next()//“接口一成功返回后,执行下一步”}})}function loadData2() {ajaxFun("promise2", ({data}) => {if (data.name) {console.log('接口二', data);it.next()//“接口二成功返回后,执行下一步”}})}function loadData3() {ajaxFun("mock", ({data,success}) => {if (success) {console.log('接口三', data);}})}function* getData() {yield loadData1()yield loadData2()yield loadData3()}const it = getData()it.next()//“启动生成器”
先弄一个遍历器出来,然后通过it.next(),启动遍历器
执行第一个接口请求,当第一个接口请求成功了,继续next(),以此类推
我想很少有人会通过Generator实现多个异步同步执行,但是async可以
下次我们尝试用async await 来实现异步请求同步化
END
