Promise是什么?
1、Promise是ES6提供的进行异步编程的解决方案
2、Promise是一个构造函数,用来封装一个异步操作,可以获取其成功或失败的值
异步编程旧的操作都是回调函数的方式:(不利于阅读和异常处理)
1)fs 文件操作
require('fs').readFile('./index.js', (err, data) => { })
2)ajax
$.get('url', (data) => { })
3)定时器
setTimeout(() => { }, 1000);
读取文件时采用回调的方式和promise的区别:
const util = require('util') const fs = require('fs') // 1、回调函数的写法 fs.readFile('./resources/为学.md', (err, data) => { if (err) throw err console.log(data + '') }) let readFile = util.promisify(fs.readFile) // 将回调函数风格的方法转为promise // 2、promise写法 readFile('./resources/为学.md').then((data) => { console.log(data + '') }) // 3、promise封装读取文件的方法 function getFile(path) { return new Promise((resolve, reject) => { require('fs').readFile(path, (err, data) => { if (err) reject(err) resolve(data) }) }) } getFile('./resources/为学.md') .then((data) => { console.log(data + '') }) .catch((err) => { console.log(err) })
promise的状态:
它的状态是实例对象中的 PromiseState 属性的值,共有3个:
pending 未决定的
resolved/fulfilled 成功
rejected 失败
它的状态变化只有两种可能,一是由pending变为resolved,一是由pending变为rejected,并且一个promise对象的状态只能改变一次,不可能由成功变为失败或由失败变为成功
如何改变promise对象的状态:
1、调用reslove(),将promise的状态由pending变为resolved
2、调用reject(),将promise的状态由pending变为rejected
3、执行throw语句,可以写成throw new Error('出错啦')也可以写成throw ‘出错啦’,将promise的状态由pending变为rejected
promise对象的值:
它的值是实例对象中的 PromiseResult 属性,保存了promise对象成功/失败的结果,没有执行成功或者失败该属性值为undefined
PromiseResult只能由resolve()和reject()改变,保存它们传来的值,在实例对象中用then()接收resolve()的值,用catch()接收reject()的值,或者是用then()方法中两个回调函数,第一个接收resolve()的值,第二个接收reject()的值
API:
Promise(excutor){}
执行器函数(excutor函数):(resolve,reject)=>{}
resolve函数:内部定义成功时调用的函数 value=>{}
reject函数:内部定义失败时调用的函数 err=>{}
注意:执行器函数会在Promise内部立即同步调用,异步操作在执行器中执行
then()方法
(onResolved,onRejected)=>{}
onResolved函数:成功的函数 (value)=>{}
onRejected函数:失败的函数 (err)=>{}
catch()方法
(onRejected)=>{}
onRejected函数:失败的函数 (err)=>{}
构造函数的方法:
Promise.resolve()
/* 如果传入的参数为非promise类型的对象,则返回的结果为成功的promise对象 如果传入的参数为promise类型的对象,则返回的结果决定了resolve的结果 */ let p = Promise.resolve(111) console.log(p) let p1 = Promise.resolve(new Promise((resolve, reject) => { reject('错误') })) p1.catch(err => { console.error(err) })
Promise.reject()
// 不管传入的是什么,都会返回失败的结果 let p = Promise.reject(123) p.catch(err => { console.log(err) }) console.log(p) // 即使传入的是一个成功的promise对象,返回的也依然是失败的结果,这个结果是成功的promise let p1 = Promise.reject(new Promise((resolve, reject) => { resolve(456) })) p1.catch(err => { console.log(err) }) console.log(p1)
Promise.all()
/* 如果数组中的promise对象都是成功的状态,那么返回的状态也是成功的,返回的结果是这三个参数组成的数组 如果数组中的promise对象有一个是失败的状态,那么返回的状态就是失败的,返回的结果是第一个失败的promise的结果 */ let p = new Promise((resolve, reject) => { resolve('成功') }) let p1 = Promise.resolve('ok') let p2 = Promise.resolve('OK!') const result = Promise.all([p, p1, p2]) console.log(result) // PromiseState 的值为 fulfilled PromiseResult 的值为 ['成功', 'ok', 'OK!']
Promise.race()
// race是赛跑的意思,返回的promise对象的状态和结果为数组中第一个执行完的promise的状态和结果 let p = new Promise((resolve, reject) => { setTimeout(() => { resolve('成功') }) }) let p1 = Promise.reject('err') let p2 = Promise.resolve('OK!') let result = Promise.race([p, p1, p2]) console.log(result) // 返回p1的状态和结果
Promise的几个问题:
1、只要promise的状态发生改变,即执行了resolve()或reject()或throw '',它指定的多个成功/失败回调函数都会调用
let p = new Promise((resolve, reject) => { // resolve('成功') // reject('错误') throw '错误' }) p.catch(err => { console.log(err) }) p.catch(err => { console.log(err) })
2、改变promise状态和指定回调函数谁先执行?正常情况下promise中都是异步任务,先执行then()方法再改变promise状态
// 如果promise中是同步任务,那么再改变promise状态再指定回调函数(执行then()方法);如果promise中是异步任务,那么先指定回调函数(先执行then()方法)再改变promise状态,这种情况居多 let p = new Promise((resolve, reject) => { setTimeout(() => { resolve('成功') }, 100) }) p.then(data => { console.log(data) // 此时是先指定回调函数再改变promise状态 }, err => { console.log(err) })
3、如何先改变promise状态再指定回调函数
1)在执行器中直接调用 resolve()/reject()----同步任务
2)延迟更长的时间才调用 then()
4、什么时候能得到数据
1)如果先指定回调,那么当状态发生改变时回调函数就会调用,得到数据----异步任务
2)如果先改变状态,那么当指定回调时回调函数就会调用,得到数据----同步任务
x