# 模拟网络请求
-
网络需求:
-
url: https://neko -> res: https://neko
-
url: https://neko + "aimer" -> res: https://nekoaimer
-
url: https://nekoaimer + ".com" -> res: https://nekoaimer.com
# 回调地狱问题
| |
| function requsetDate(url) { |
| return new Promise(resolve => setTimeout(() => resolve(url), 2000)) |
| } |
| |
| |
| requsetDate('https://neko') |
| .then(res => { |
| requsetDate(res).then(res => { |
| requsetDate(res + 'aimer').then(res => { |
| requsetDate(res + '.com').then(res => { |
| console.log(res) |
| }) |
| }) |
| }) |
| }) |
# 优化方案
- Promise then 方法的返回值也是 Promise, 那么我们可以 return 出去
- 这种方式就要清晰不少,但依然不是我认为最好的处理的方案或者说是结果
| |
| function requsetDate(url) { |
| return new Promise(resolve => setTimeout(() => resolve(url), 2000)) |
| } |
| |
| requsetDate('https://neko') |
| .then(res => { |
| return requsetDate(res + 'aimer') |
| }) |
| .then(res => { |
| return requsetDate(res + '.com') |
| }) |
| .then(res => { |
| console.log(res) |
| }) |
# Promise + generator 方案
- 这种方案从 getData () 能够清晰的得出每次结果
| |
| function requsetDate(url) { |
| return new Promise(resolve => setTimeout(() => resolve(url), 2000)) |
| } |
| |
| |
| function* getData() { |
| const res1 = yield requsetDate('https://neko') |
| console.log(res1) |
| |
| const res2 = yield requsetDate(res1 + 'aimer') |
| console.log(res2) |
| |
| const res3 = yield requsetDate(res2 + '.com') |
| console.log(res3) |
| } |
| |
| |
| const generator = getData() |
| generator.next().value.then(res => { |
| generator.next(res).value.then(res => { |
| generator.next(res).value.then(res => { |
| generator.next(res) |
| }) |
| }) |
| }) |
- 那么有人可能会有疑问了,下面的 generator 不也是回调地狱吗,代码量看上去更麻烦了呀?
- 别急,我会进行一些处理,之后就会发现这种处理方式结构清晰,可重复利用是非常优秀的
# 自动执行 generator 函数
| |
| function requsetDate(url) { |
| return new Promise(resolve => setTimeout(() => resolve(url), 2000)) |
| } |
| |
| |
| function execGenerator(genFn) { |
| const generator = genFn() |
| function exec(res) { |
| const result = generator.next(res) |
| if (result.done) return result.value |
| result.value.then(res => exec(res)) |
| } |
| exec() |
| } |
| |
| |
| function* getData() { |
| const res1 = yield requsetDate('https://neko') |
| const res2 = yield requsetDate(res1 + 'aimer') |
| const res3 = yield requsetDate(res2 + '.com') |
| console.log(res3) |
| } |
| |
| execGenerator(getData) |
# co(TJ)
| function requsetDate(url) { |
| return new Promise((resolve, reject) => { |
| setTimeout(() => resolve(url), 2000) |
| }) |
| } |
| |
| function* getData() { |
| const res1 = yield requsetDate('https://neko') |
| const res2 = yield requsetDate(res1 + 'aimer') |
| const res3 = yield requsetDate(res2 + '.com') |
| console.log(res3) |
| } |
| |
| const co = require('co') |
| co(getData) |
# async & await 实现
- 这种方案本质上是 generator 与 Promise 的语法糖
- 所以最终的解决方案就是下面这种了
| function requsetDate(url) { |
| return new Promise((resolve, reject) => { |
| setTimeout(() => resolve(url), 2000) |
| }) |
| } |
| |
| async function getData() { |
| const res1 = await requsetDate('https://neko') |
| const res2 = await requsetDate(res1 + 'aimer') |
| const res3 = await requsetDate(res2 + '.com') |
| console.log(res3) |
| } |
| getData() |