本文已参与「新人创作礼」活动,一起开启掘金创作之路。
什么是Promise
ES6中Promise对象是一个构造函数,因为Javascript是单线程的,为了解决异步编程,用promise来延迟计算和异步计算。
Promise的特点
- 对象状态不收外界影响,只受异步结果控制promise的状态:pending、fulfilled、rejected(进行中、已成功、已失败)
- 一旦状态改变,就不会再变。promise的状态只能由pending变为fulfilled或者pending变为rejected两种状态,且两种状态只能存在一个,一旦转变不能更改。
resolve和reject
当一个函数作为参数传入Promise中时,这个函数有两个参数分别为resolve和reject。
-
resolve:将promise的状态由pending变为fulfilled,并把结果作为参数传出去
-
reject:pending变为rejected,并把错误作为参数传出去
使用
-
创建一个Promise
let P = new Promise(function(reslove,reject){ //异步 setTimeout(function(resolve,reject){ console.log('success') },1000) }) -
Promise中的then:可以接受两个参数,第一个是resolve的回调,第二个是reject的回调
function fn1() { let P = new Promise(function(resolve,reject){ setTimeout(function(){ console.log('fn1 success'); resolve(111111) },1000) }); return P; } fn1() .then(function(data){ console.log(data) }) -
Promise中的catch:在then中执行resolve的回调错误时会在catch中把错误抛出,并继续执行代码
function fn1() { let P = new Promise(function(resolve,reject){ setTimeout(function(){ console.log('fn1 success'); resolve(111111) },1000) }); return P; } fn1() .then(function(data){ console.log(data) }) .catch(function(data){ console.log(data) }) -
Promise.all:可以接受一个数组参数,在执行完所有异步之后再进入then,并把所有得到的值传到then中。
function fn1() { let P = new Promise(function(resolve,reject){ setTimeout(function(){ console.log('fn1 success'); resolve(111111) },1000) }); return P; } function fn2() { let P = new Promise(function(resolve,reject){ setTimeout(function(){ console.log('fn2 success'); resolve(222222) },2000) }); return P; } Promise .all(fn1(),fn2()) .then(function(data){ console.log(data) })
解决了什么问题
-
回调函数:当一个函数作为参数传到另一个函数当中,他并不会立即执行,而是是回头再调用的函数,那什么时候再调用呢?当满足一定的条件后函数才会被执行,这种函数被称为回调函数。
setTimeout(()=>{ console.log('I am the callback function'); },5000) -
回调地狱:因为Javascript是单线程的,异步的代码不能一定按照顺序执行,为了让代码按照顺序执行,会在回调函数中套用回调函数,导致代码的可读性和维护性较差,这种形式被称为回调地狱。
setTimeout(()=>{ console.log(1) setTimeout(()=>{ console.log(2) setTimeout(()=>{ console.log(3) },1000) },2000) },3000) -
用promise改写
function fn1() { let P = new Promise(function(resolve,reject){ setTimeout(function(){ console.log('fn1 success'); resolve(111111) },1000) }); return P; } function fn2() { let P = new Promise(function(resolve,reject){ setTimeout(function(){ console.log('fn2 success'); resolve(222222) },2000) }); return P; } function fn3() { let P = new Promise(function(resolve,reject){ setTimeout(function(){ console.log('fn3 success'); resolve(333333) },3000) }); return P; } fn1() .then(function(data){ console.log(data) return fn2() }) .then(function(data){ console.log(data) return fn3() }) .then(function(data){ console.log(data) })