前世今生
javascript语言中所有执行程序都是单线程,javascript为了解决程序阻塞(I/O操作、事件操作),也支持了异步操作。但是异步操作在javascript处理都是通过回调callback方法,来处理的。为了解决javascript回调地狱问题,promise出现了。
promise概述
- promise有三个状态:
1、pending[待定]初始状态
2、fulfilled[实现]操作成功
3、rejected[被否决]操作失败
promise状态一经改变,不会再变。 - Promise对象的状态改变,只有两种可能:
从pending变为fulfilled
从pending变为rejected。
promise API
- Promise.prototype.then
- Promise.prototype.catch
- Promise.prototype.finally
- Promise.resolve
- Promise.reject
- Promise.all
- Promise.race
promise使用案例
(async () => f())().then(res => console.log).cathc(res => console.log)(() => new Promise(resolve => resolve(f())))().then(res => console.log).cathc(res => console.log)
promise使用
var ajax = () => {return new Promise((resolve,reject) => {$.ajax({url,type:'get',success:() => {resolve(res)},error:(res) => {reject(res)}})})}ajax().then(res => {console.log(res)}).cathch(res => {console.log(res)})
Promise.prototype.then
then方法执行来自promise中resolve返回的结果例:
var fn = () => {return new Promise((resolve,reject) => {setTimeout(() => {resolve('hello word')})})}//这里then方法执行来自promise中resolve返回的结果fn().then(res => console.log(res))//hello word//注:then方法可以接受两个function 如果有第二个function相当语catch 接受来自reject的结果fn().then(res=>{},err=>{console.log(err,'err')})
Promise.prototype.catch
catch执行来自promise中reject返回的结果
var fn = () => {return new Promise((resolve,reject) => {setTimeout(() => {reject('hello word')})})}//catch执行来自promise中reject返回的结果fn().then(res => console.log(res)).catch(res => console.log('error',res))//error hello word
promise.prototype.finally
finally不管结果是在then还是catch都会执行
fn().then(res => console.log(res)).catch(res => console.log('error',res)).finally(res => console.log('finally',res))//finally不管结果是在then还是catch都会执行error hello wordfinally undefined
promise.resolve
promise.resolve可以理解成是new Promise((resolve,reject) => {}) resolve 的简写方式
Promise.resolve('hello word').then(res => {console.log(res)})//hello word
promise.reject
promise.resolve可以理解成是new Promise((resolve,reject) => {}) reject 的简写方式
Promise.reject('hello word').then(res => {console.log(res,'error')})//hello word error
promsie.all
promsie.all接受一个数组array 数组元素都是一个或多个promsie、所有的元素promsie必须都执行then、
最后才会执行promise.all().then 否则执行promise.all().catch()
var f1 = async() => 'hello'var f2 = async() => 'word'var f3 = async() => Promise.reject('xixi')Promise.all([f1(),f2(),f3()]).then(res => console.log(res)).catch(res => console.log(res,'error'))//promsie.all接受一个数组array 数组元素都是一个或多个promsie、//所有的元素promsie必须都执行then、//最后才会执行promise.all().then 否则执行promise.all().catch()//这里执行结果是xixi error
Promise.race
promsie.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3]);
上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。
下面是一个例子,如果指定时间内没有获得结果,就将 Promise 的状态变为reject,否则变为resolve。
const p = Promise.race([fetch('/resource-that-may-take-a-while'),new Promise(function (resolve, reject) {setTimeout(() => reject(new Error('request timeout')), 5000)})]);p.then(console.log).catch(console.error);
上面代码中,如果 5 秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。
promise总结
**
1.promise中then或者catch都是可以return 一个结果的,可以是任意值,也可以是重新定义promise。
2.promise中使用return一个的值,它相当于Promise.resolve(‘任意值’)。
3.then方法其实也是可以接受两个参数的,第二个参数也是function,作用用catch一样。
4.race方法时由第一个转变状态的小Promise的状态决定,第一个是成功态,则转成功态,第一个失败态,则转失败态。
5.reject方法可以生成一个失败的Promise 、Promise.reject(‘出错了’)等同于new Promise((resolve, reject) => reject(‘出错了’))
promise值得借鉴的写法
1.Promise.resolve({then:fn2})的用法
//定义异步方法var fn2 = (resolve,reject) => {setTimeout(() => {reject('fn2')},800)}//使用异步方法(async () => Promise.resolve({then:fn2}))().then(console.log).catch(console.log)//也可以使用(async () => new Promise(fn2))().then(console.log).catch(console.log);console.log('haha');
2.定义一个自执行的promise
//定义一个自执行的promiseconst f = () => console.log('now');(() => new Promise(resolve => resolve(f())))();console.log('next');// now// next
3.async 、Promise结合用法
var f1 = (resolve,reject) => {resolve('haha')}var f2 = (resolve,reject) => {setTimeout(() => {resolve('f2')},1000)}var f3 = (resolve,reject) => {setTimeout(() => {resolve('f3')},200)}(async () => {let res1 = await new Promise(f1);let res2 = await new Promise(f2);let res3 = await new Promise(f3);console.log(res1);console.log(res2);console.log(res3);return 'ok l'})().then(console.log).catch(console.log)
