1、promise
promise:ES6引入的一门新技术,是js中进行异步编程的新解决方案。从语法上来说就是一个构造函数。
异步编程:fs 文件操作,数据库操作,ajax,定时器。
promise优点:支持链式调用,可以解决回调地狱问题。指定回调函数的方式更加灵活,可以在异步任务结束后指定,还可以指定多个。
2、promise语法
promise实现:const p=new Promise((resolve,reject)=>{});,resolve 解决 函数类型,reject 拒绝 函数类型,当成功了调用resolve,失败了调用reject。当调用了resolve时(可以加上参数调用),会自动将promise的状态设置为成功(此时参数会成为成功结果值),reject则设置为失败。
then方法:p.then(()=>{},()=>{}),两个参数均为回调函数(可以分别带上参数value,reason,带参数可以省略括号),前一个为状态成功调用的函数,value为成功结果值,后一个为状态失败调用的函数,reason为失败结果值。then方法的返回结果是一个新的promise对象。
3、promise实现以下功能
fs读取文件:引入文件,const fs = require('fs')。普通fs方法:fs.readFile('../文档/test.txt', (err, data) => {if (err) throw err; console.log(data.toString());})。promise方法:const p = new Promise((resolve, reject) => {fs.readFile('./文档/test.txt', (err, data) => {if (err) reject(err);resolve(data);});});。
Ajax请求:跟fs类似。
util.promisify():该方法可以将别的函数格式化为promise方法,如,将fs.readFile作为参数,可以直接得到一个读取文件的promise函数,可以直接调用这个函数,传入参数(路径),调用then即可。
4、promise实例对象的属性
PromiseStatus:promise的状态,是promise实例对象的一个属性,状态只能修改一次。默认值:pending,其他值:resolved/fullfilled(成功),rejected(失败)。
PromiseResult:promise的异步任务的结果值,是promise实例对象的一个属性。resolve和reject函数可以修改这个结果值。
5、promise的API
promise构造函数:Promise(excutor){}。excutor函数:执行器(resolve,reject)=>{}。resolve函数:内部定义成功时我们调用的函数value=>{}。reject函数:内部定义失败时我们调用的函数reason=>{}。excutor会在promise内部立即同步调用,异步操作在执行器中执行。
实例对象的then方法:如上面then方法一样。
实例对象的catch方法: (onReject)=>{},失败的回调函数。
函数对象的resolve方法:如果传入的参数为非promise对象,则返回的结果为成功promise对象,如果传入的是promise对象,则参数的结果决定了结果。
函数对象的reject方法:返回一个失败的promis对象。不管参数是什么,都是失败的对象,返回的结果就是该参数。
函数对象的all方法:返回一个新的promise,参数是多个promise对象,只有所有的promise对象都成功,状态才是成功,结果值为这多个对象结果组成的数组;如果有一个失败了,返回失败对象,结果值为失败的对象的结果值。
函数对象的race方法:返回一个新的promise,参数是多个promise对象,返回结果是第一个改变状态的对象的结果值,状态就是该状态。
6、promise的关键问题
改变promise对象的状态:通过调用resolve函数,可以将状态由pending变为resolved。调用reject函数,可以将pending变为rejected。抛出错误,可以使用trow语句。
执行多个回调:使用then指定多个回调函数,调用多次then方法,这样状态改变后这几个回调函数都会执行。
状态改变和指定回调谁先谁后:当promise里面是同步任务时,先改变状态再指定回调函数。当promise里面是异步任务(封装fs,数据库操作,Ajax请求,定时器)时,里面有定时器之类的,就是先指定回调再改变状态。想先改变状态可以在then方法里面加一个延时更久的定时器。
then方法的返回结果:返回结果由指定的回调函数的结果决定。如果抛出异常,新promise变为rejected,reason为抛出的异常;如果返回的是非promise值,新promise变为resolved。value为返回的值;如果返回的是一个promise,此promise的结果会成为新的promise的结果。
串联多个任务:在then方法里面嵌套promise,链式调用,通过then方法的链式调用串联多个任务。
promise异常穿透:在then方法进行链式调用时,可以只在最后指定失败的回调,就可以处理前面一切错误。
中断promise链:有且只有一种方式,就是返回一个pending状态的promise对象,这样状态没有改变,在这之后的都不会执行。
7、自定义封装(手写)promise
定义整体结构:自定义一个Promise函数,就可以实现覆盖,调用时用的就是自己定义的promise。一个构造函数+一个then方法。