首先解释一下什么是同步、什么是异步
同步:做饭的时候,先烧水,等水烧好的时候再去做菜
异步:做好的时候,先烧水,等待水烧好的过程中,同时去做菜
使用promise的目的就是为了避免 callback hell(地狱回调)例如:
setTimeout(() => {
console.log(1)
setTimeout(() => {
console.log(2)
setTimeout(() => {
console.log(3)
}, 3000)
}, 2000)
}, 1000)
像这种代码可读性和可维护性都不高,所以es6才提出了promise这种方法。
promise一共有三种状态
1.pending //既不是成功,也不是失败
2.fulfilled //成功
3. rejected //失败
以下是例子
//resolve代表成功,reject代表失败
new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log(1)
resolve()
},1000).then(res=>{
setTimeout(()=>{
console.log(2)
},2000)
})
})
这样就解决了地狱回调的问题。
除此之外,promise还有两个很重要的方法 Promise.all
Promise.all代表等待全部promise执行完成后再执行。
举个例子
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p1')
resolve('p1') //可以进行传参
}, 1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p2')
resolve('p2')
}, 2000)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p3')
resolve('p3')
}, 3000)
})
Promise.all([p1, p2, p3]).then(res => {
console.log('全部完成')
console.log(res)
}).catch(err => {
console.log('失败')
console.log(err)
})
promise.all会等待p1,p2,p3完成请求之后才会执行,如果执行失败才会进入catch方法。
console的结果如下:
其中promise.all成功调用之后res接受的参数是p1、p2、p3 resolve()传递进来的。
如果我们把p1、p2、p3 其中一个改为调用失败的话
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p1')
reject('p1') //可以进行传参
}, 1000)
})
那么promise.all就会执行失败,也就是promise.all一定要三个都执行成功之后才能够成功执行。
还有一个方法是Promise.race,它的意思是,只要有一个任务完成了就算是完成了,还是刚刚那个例子,把Promise.all改为Promise.race的话,输入的结果如下:
promise.race一般用于判断是否请求超时。
async、 await
在小程序中默认是不支持async、await
的,如果需要使用的话,方法如下
1.在你的项目中创建一个文件夹utils
2.在utils文件夹下创建一个js文件runtime.js
runtime.js的代码如下:runtime.js
3.在你需要使用的小程序js中引入
//注意这里一定要用regeneratorUntime,不用的话会报错
import regeneratorUntime from '../../utils/runtime.js'
然后就可以开始使用 async await
了。
那么async await怎么使用呢?下面举个例子说明async、await
怎么使用
首先定义一个定时的函数
timeout() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(1)
resolve('resolve')
}, 1000)
})
}
(这个函数会在1s之后在控制台打印出一个1)
然后我需要在一个函数中调用这个函数并取得这个值,例如我需要在foo这个函数中调用这个方法,然后在页面初始渲染的时候渲染这个foo()
函数
async foo(){
this.timeout()
}
显然如果使用上面那一段代码的话在控制台是打印不出1的,因为timeout()
函数是一个异步的操作
所以我们就需要使用到async、await
方法
async foo(){
let res = await this.timeout()
console.log(res)
}
这样才能保证,timeout()函数执行完成之后才赋值给res
注意! 使用await前面一定要有一个async,不然的话执行是没有效果的。
结果如下:
大家可以看一下代码行数,是不是先执行了timeout这个方法然后才执行foo函数中的console。
以上就是简单的async、await
的简单使用方法,实际使用中肯定比这个复杂的多,希望这篇文章对大家有所帮助