异步编程方案之Promise
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
为什么需要Promise
- 我们之前写代码,可能会出现函数嵌套函数,如果多个嵌套,结构就会很乱,也不容易维护,于是Promise就出现了。
什么是Promise
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
Promise的特点
-
对象的状态不受外界影响,它有三种状态,
pending
(进行中)、fulfilled
(已成功)、rejected
(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。 -
一旦状态改变,就不会再变,任何时候都可以得到这个结果。它的状态可以从pending变为fulfilled,或者从pending变为rejected。
Promise的基本用法
- 首先,我们创建一个Promise
const testPormise=new Promise((resovle,reject)=>{
console.log("hi,Pormise");
});
//输出hi,Pormise
- 上面代码,我们创建了一个Promise,它会立即执行,输出hi,Pormise。下面我们改变一下它的状态:
const testPormise=new Promise((resovle,reject)=>{
console.log("hi,Pormise");
let test=true;
if(test){
resovle('成功~')
}else{
reject("失败了")
}
});
testPormise.then((res)=>{
console.log(res)
}).catch((erro)=>{
console.log(erro)
})
//输出:成功~
- 我们在内部加了一个判断,当test为true时候,即改变当前状态为成功,此时会走进then方法,且会也会把参数接收过来,此时就会打印出成功。如果改变test,则调用reject,这时候就可以用
catch
捕获到失败状态。
Promise中finally方法
- 下面再看一下Promise中的
finally
方法,这个方法代表无论成功和失败都会执行:
const testPormise = new Promise((resovle, reject) => {
console.log("hi,Pormise");
let test = true;
if (test) {
resovle('成功~')
} else {
reject("失败了")
}
});
testPormise.then((res) => {
console.log(res)
}).catch((erro) => {
console.log(erro)
}).finally(() => {
console.log('执行了finally')
})
//输出 成功~
//输出 执行了finally
finally
方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled
还是rejected
。这表明,finally
方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。
Promise中all方法
all
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const test1=new Promise((resovle,reject)=>{
resovle()
});
const test2=new Promise((resovle,reject)=>{
resovle()
})
const test3=new Promise((resovle,reject)=>{
resovle()
})
const promiseAll=Promise.all([test1,test2,test3])
.then(()=>{
console.log('都成功')
})
.catch(()=>{
console.log('有失败')
})
//输出 都成功
- 上面代码创建了3个Promise,他们三个的状态都为
fufilled
,才会返回fulfilled
,否则返回rejected
。上面代码如果有一个调用了reject,就会进入catch,输出:有失败
Promise中race方法
race
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const test1=new Promise((resovle,reject)=>{
setTimeout(()=>{
resovle('test1')
},500)
});
const test2=new Promise((resovle,reject)=>{
setTimeout(()=>{
resovle('test2')
},1000)
})
const test3=new Promise((resovle,reject)=>{
setTimeout(()=>{
resovle('test3')
},400)
})
const promiseAll=Promise.race([test1,test2,test3],()=>{
})
.then((res)=>{
console.log(res)
})
.catch((res)=>{
console.log(res)
})
//输出:test3
- 与
all
方法不同的是,如果其中有一个实例率先改变了状态,promiseAll的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数,所以上面代码会输出test3。