学习 promise、generator和最新的 await。
假设现在有这么一个需求:
用户输入关键词查询记录,先按照书籍ISBN码进行搜索,如果没有搜索到,就按照书籍名称搜索,如果没有搜索到,就按照借阅会员学号搜索,如果没有搜索到,就按照借阅会员姓名搜索。
数据是这样的:
1 | { |
为了方便使用了json-server
作为接口返回这些数据。
- http://127.0.0.1:3000/record?author=林海音 会返回第四条数据
- http://127.0.0.1:3000/record?title=JavaScript权威指南 会返回第六条数据
详细使用可以查看 json-server 文档。
callback
由于每一次的搜索,都依赖于上一次的结果,所以必须在上一次查询的结果中进行下一次的查询。
这是我之前的写法:
1 | var req = require('request'); |
如果条件再多几个,嵌套更深,整个代码会往右边偏。。。。为了解决这个问题,出现了 Promise。
Promise
Promise 是对象,有 then 和 catch 方法,可以获取到成功和失败各自的返回结果。
1 | function temp(params) { |
定义了一个temp
函数,调用该函数后会返回一个 promise 对象,调用该对象的 then 方法接收成功的返回结果,调用 catch 方法接收失败的返回结果。
所以上面的例子这么改写:
1 | var req = require('request'); |
可以很明显看到不存在嵌套了,而是采用了链式调用。。。重点在于catch
方法返回一个新的 promise 对象。
generator
generator 可以将异步函数变成同步的。道理很简单, yield 关键字会暂停函数的运行,直到返回值了才继续往下执行。
参考 - http://www.voidcn.com/blog/zhiweiusetc/article/p-6093190.html
使用 generator 改写上面的例子:
1 | var req = require('request'); |
不是嵌套,也不是链式调用,而是按照代码顺序。而且是在开始时定义一个变量,通过接口查询后,就能够直接拿到值,写起来像是同步的。
这个例子重点在 yield 返回 generatorltr.next() 传的参数。
async of es7
代码比前面都简单,不过需要使用 babel 才能够使用到 es7 的这个新特性。直接上代码:
1 | ; |
看起来和 generator 一模一样,因为 async 其实就是 generator 的语法糖。
一比较就会发现,async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成 await,仅此而已。
github repository
https://github.com/ltaoo/learnCallback
参考
基础
本文参考
拓展阅读