Promise
首先我们要明白,为什么要使用promise,promise旨在于解决异步编程问题,同步任务与异步任务最大的区别在于,异步任务中我们不知道什么时间会结束,等待任务结束后再开启另一个任务,这时就会出现回调地狱,我们写的代码具有非常不好的可读性。
例如:
listen('click', function handler(evt){
setTimeout(function request(){
ajax({
url: "http://d.falkg.com",
success: function(res){
if(res.txt == '1'){
handler()
}else {
request()
}
}
})
},500)
})
以上这种写法就比较难受,首先执行listen,然后过500ms去执行ajax,ajax完成后判断txt,然后再去执行其他函数。这样就很容易出现回调问题。
因此我们需要一个承诺,恰好promise就是这样的角色。
承诺
Promise实例有3个状态,Pending(进行中)、Resolved(已完成)、Rejected(已拒绝)。
例如:
let promise = new Promise((resolve, reject)=>{
setTimeout(function request(){
let txt = '1'
if(txt == '1'){
resolve(txt)
}else {
reject('error')
}
},500)
})
这样就完成了一个承诺,成功时调用resolve,失败时调用reject,我们怎么调用呢?
promise.then(res=>{
//执行成功的回调
console.log(res)
},err=>{
//执行失败的回调
console.log(err)
})
then方法的返回值,如果不是一个promise,就会被包装成一个promise,因此promise可以链式调用then
promise串行
例如:
ajax('first')
ajax('second')
ajax('third')
普通写法
ajax('first').success(function(res){
ajax('second').success(function(res){
ajax('third').success(function(res){
//串行执行完毕
})
})
})
使用promise的链式调用
let promise = new Promise((resolve, reject)=>{
ajax('first').success(function(res){
resolve(res)
})
})
promise.then(res=>{
return new Promise((resolve, reject)=>{
ajax('second').success(function(res){
resolve(res)
})
})
}).then(res=>{
return new Promise((resolve, reject)=>{
ajax('third').success(function(res){
resolve(res)
})
})
}).then(res=>{
// 这里就可以处理结果了,是不是方便了很多呢
})
以上是多个异步事件串行,那么并行怎么处理呢,如果异步函数之间没有先后顺序,怎么实现呢
Promise.all 与 Promise.race
promise.all接收一个数组,数组的每一项都是一个promise对象。当数组中所有的promise都达到resolved状态后,promise.all才会变成resolved状态。如果有一个回调返回了失败rejected,那么整体就会返回rejected。
例如:
let promise1 = new Promise((resolve, reject)=>{
ajax('first').success(function(res){
resolve(res)
})
})
let promise2 = new Promise((resolve, reject)=>{
ajax('second').success(function(res){
resolve(res)
})
})
let promise3 = new Promise((resolve, reject)=>{
ajax('third').success(function(res){
resolve(res)
})
})
Promise.all([promise1, promise2, promise3]).then(res=>{
// 这里按顺序保存所有promise的结果
// 但有一点需要注意,以上3个异步函数执行的时间顺序是不固定的,.all只是保证全部完成,但谁先完成谁后完成,是不固定的。
})
Promise.race是竞速模式,与all不同的是,第一个结果将会被then返回,如果第一个执行完成的结果是resolved,那么整个race就会返回resolved,如果第一个完成的异步函数返回rejected,那么整个race就会返回rejected。
例如:
let promise1 = new Promise((resolve, reject)=>{
ajax('first').success(function(res){
resolve(res)
})
})
Promise.race([promise1, timeoutPromise(3000)]).then(res=>{
// 如果promise1的执行时间超过了3s,那么久不会再继续执行了,为异步函数设置了超时时间
})
以上就是我对promise的简单理解