promise是异步编程的一种解决方案,那么为什么要使用promise呢?
比如说,当我们封装一个网络请求,因为不能立即拿到结果,所以不能像简单的函数一样将结果返回,所以我们会传入另一个函数,在请求成功时将数据通过该函数回调出去。
但是,当请求比较复杂时,就会出现回调地狱。
$.ajax(url, function (data1) {
$.ajax(data1['url2'], function(data2) {
$.ajax(data2['url3'], function(data3) {
console.log(data3)
})
})
})
可以看到,我们需要通过一个url从服务器加载一个data1,data1中包含了下一个请求的url2,
这时就需要从data1中取出url2,在加载url2,再去请求url3。
这样的话,代码较难看,而且逻辑乱且不易维护
那么promise能更好的解决这个问题,下面我们用定时器模仿网络请求。
setTimeout(() => {
console.log('hello world')
setTimeout(() => {
console.log('hello javascript')
setTimeout(() => {
console.log('hello vue')
},1000)
},1000)
},1000)
通过promise
new Promise((resolve,reject) => {
//第一次网络请求
setTimeout(() => {
resolve()
},1000)
}).then(() => {
console.log('hello world')
return new Promise((resolve,reject) => {
//第二次网络请求
setTimeout(() => {
resolve()
},1000)
}).then(() => {
console.log('hello javascript')
return new Promise((resolve,reject) => {
//第三次网络请求
setTimeout(() => {
resolve()
},1000)
}).then(() => {
console.log('hello vue')
})
})
只要有异步操作,我们就返回一个promise
对象,这样代码虽然更多了,但逻辑更清晰了,也更好维护
promise的三种状态
pending:等待状态, 比如正在进行网络请求,或者定时器没到时间
fulfilled: 成功状态,当我们主动回调resolve时,就处于该状态,并且回调.then()
rejected:拒绝状态,当我们主动回调reject时,就处于该状态,并且回调.catch()
promise.all
promise.all可以将多个promise实例包装成一个新的promise实例。同时,成功和失败的返回值是不同的,
成功的时候返回一个数组,失败时则返回最先被reject失败的状态的值。
所有的请求都完成时,才返回一个数组
只要有一个失败了,就先返回这个失败的请求
let p1 = new Promise((resolve,reject) => {
resolve('成功了')
})
let p2 = new Promise((resolve,reject) => {
resolve('success')
})
let p3 = new Promise((resolve,reject) => {
reject('失败了')
})
Promise.all([p1, p2]).then(res => {
console.log(res) //[ '成功了', 'success' ]
}).catch(err => {
console.log(err)
})
Promise.all([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err) // 失败了
})
promise.race
顾名思义,promise.race就是赛跑的意思,就是说promise.race([p1, p2, p3])里哪个结果捕获的快,就返回哪个结果
不管成功还是失败
let p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('成功了')
},1000)
})
let p2 = new Promise((resolve,reject) => {
setTimeout(() => {
reject('失败了')
},500)
})
Promise.race([p1, p2]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
async/await
async/await是es7出的一种解决异步的一种方案, 背后原理就是promise,当一个函数前面加上async,那么他就成了一个异步函数
async
async function f1() {
return "abc"
}
console.log(f1())
上面的代码其实等同于
return new Promise(resolve => {
resolve('abc')
})
与await结合
async function f3() {
return 'f3';
}
async function f4() {
return 'f4';
}
async function f5() {
var a = await f4();
var b = await f5();
console.log(a, b)
}
f5()
await会阻塞后面的代码,等主程序执行完,再回来执行
网友评论