- 一个异步请求套着一个异步请求,一个异步请求依赖于另一个的执行结果,使用回调 的方式相互嵌套。
回调地狱缺点:
解决回调地狱
使用ES6中的Promise
-
Promise
有三种状态:pending/reslove/reject 。pending就是未决,resolve可以理解为成功,reject可以理解为拒绝。- 同时Promise常用的三种方法
then
表示异步成功执行后的数据状态变为reslove catch
表示异步失败后执行的数据状态变为reject all
表示把多个没有关系的Promise封装成一个Promise对象使用then返回一个数组数据。
function f() {
let promise = new Promise((resolve, reject) => {
//模拟异步
setTimeout(()=>{
resolve('prom')
},1000)
})
return promise;
}
-
- Promise 构造函数有两个变量
resolve
用于返回异步执行成功的函数 reject
用于返回异步执行失败的函数。配合then与catch一起使用 - 使用then获取数据
function f1() {
//返回一个Promise用于下一次调用then
return f().then(data=>{
// 返回的数据用于下一次then使用
return data+'ise'
})
}
-
- 使用then方法 获取到上一步resolve返回的数据
- 获取数据
f1().then(data=>{
console.log(data)
})
console.log("hello word")
-
- 如果猜的不错输出应该为promise

输出了promise 说明上面是正确的,并且先输出 hello word 后输出promise 说明Promise
是异步执行的
- 但是如果过多的使用then 也会照成新的执行流程问题。
ES6中的Generator
(生成器)
-
Generator
(生成器)是一种有效利用内存的机制,一边循环一边计算生成数值的机制。通过配合Promise可以更加优雅的写异步代码- 下面我们来试试:
function f1() {
let promise = new Promise((resolve, reject) => {
setTimeout(function () {
resolve("hello word")
})
})
return promise;
}
-
- 首先我们先用Promise分装一个异步请求模拟ajax。
- 构建一个生成器函数
function *f() {
let x = yield f1();
console.log("ni hao")
}
-
- 构建生成器非常简单 只需要在函数方法名前面加一个
*
这个函数就是一个生成器函数,函数体中有一个yield
关键字,简单点说yield
类似return
也是返回值的,区别在于当程序 执行到yield后会返回yield后面的表达式,并且程序暂停在这里保存当前值状态,程序只是暂停在这里并没有中止。 - 获取生成器的值
var it = f();
it.next().value.then(data=>{
console.log(data)
})
console.log(123)
it.next()
console.log(it.next())
-
- 使用next()方法可以获取到yield第一次暂停的值返回的是
{ value: 值 done: true }
value表示yield返回的值,done表示是否迭代完毕。当然也可以使用netx(10)来给yield设置下次执行的值。 - 输出结果

通过结果我们看到生成器也是异步执行。
ES7async/await
(异步等待)
function f() {
return new Promise((resolve, reject) => {
setTimeout(()=>{
resolve("hello word")
},1000)
})
}
async function a(){
var data = await f();
return data;
}
-
- 函数前面加
async
表示该函数是一个异步函数 await
表示等待一个异步值的到来, - 获取值
var a = a()
a.then(data=>{
console.log(data)
})
-
- 生成器返回的是一个迭代器,而 异步函数返回的是一个Promise,异步函数可以以更加方便的同Promise结合使用来书写同步代码风格的异步执行。