一、简介
1)抽象表达:
Promise是一门新的技术(ES6规范)
Promise是JS中进行异步编程的新解决方法
2)具体表达:
从语法上来说:Promise是一个构造函数
从功能上来说:Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值
二、Promise的状态和结果值
1)状态(PromiseState)的改变:
pending (未决定的) ==> resolved / fulfilled(成功)
pending (未决定的) ==> rejected(失败)
有且只有这2种变化,且一个promise对象只能改变一次
无论变为成功还是失败,都会有一个结果数据
成功的结果数据一般称为:value,失败的结果数据一般称为:reason
2)结果值(PromiseResult):
resolve():将promise对象的状态设置为【成功】
reject():将promise对象的状态设置为【失败】
三、Promise的相关API
1.Promise()构造函数
Promise(executor){}
executor函数:执行器(resolve,reject)=>{}
resolve函数:内部定义成功时我们调用的函数 value =>{}
reject函数:内部定义失败时我们调用的函数 reason =>{}
注意:executor会在Promise内部立即同步调用,异步操作在执行器中执行
2.Promise.prototype.then()方法
(onResolved,onRejectd)=> {}
onResolved函数:成功的回调函数 (value)=>{}
onRejectd函数:失败的回调函数(reason)=>{}
注意:指定用于得到成功value的成功回调和用于得到失败reason的失败回调会返回一个新的promise对象
3.Promise.resolve()方法
value =>{}
value:成功的数据或promise对象
说明:返回一个成功/失败的promise对象
注意:
如果传入的参数为 非 promise 类型的对象,则返回的结果为成功的 promise 对象
如果传入的参数为 promise 对象,则参数的结果决定了返回的 promise 对象结果
4.Promise.reject()方法
reason =>{}
reason:失败的原因
说明:返回一个失败的promise对象
5.Promise.all()方法
promises =>{}
promises:包含n个promise的数组
注意:返回一个新的promise,只有所以的promise都成功才成功,只要有一个失败,则直接失败
6.Promise.race()方法
promises =>{}
promises:包含n个promise的数组
注意:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
四、Promise关键问题
1.如何改变promise状态
resolve(value):将pending ==> resolved / fulfilled
reject(reason):将pending ==> rejected
抛出异常:如果当前是 pending 就会变成为 rejectd
2.一个promise指定多个成功/失败回调函数,都会调用吗
当promise改变为对应状态时都会调用
3.改变promise状态和指定回调函数谁先谁后
都有可能,正常情况下(即异步调用)是先指定回调再改变状态,但饿可以先改变状态再指定回调(同步调用)
同步调用:在执行器中直接调用 resolve()/ reject()
异步调用:延迟更长时间才调用 then()
数据的获得:
如果先指定的回调,那么当状态发送改变时,回调函数就会调用,得到数据
如果先改变状态,那当指定回调时,回调函数就会调用,得到数据
4.promise.then()返回的新promise的状态由什么决定
简单表述:由then()指定的回调函数执行的结果决定
1)如果抛出异常,则新 promise 变为 rejected,reason为抛出异常
2)如果返回的是非 promise 的任意值,新 promise 变为 resolved,value为返回值
3)如果返回的是另一个新 promise,此 promise 的结果就会成为新promise的结果
5.promise如果串联多个操作任务
promise 的 then() 返回一个新的 promise,可以开成then()的链式调用,通过其链式调用则可以串联多个操作任务
6.promise异常传透
当使用 promise 的 then 链式调用时,可以在最后指定失败的回调,而此时前面任何操作出现了异常,都会传到最后失败的回调中处理
7.中断promise链
当使用 promise 的 then 链式调用时,在中间中断(即在回调函数中返回一个 pending 状态的 promise 对象),不再调用后面的回调函数
五、Promise相关体验
使用promise实践抽奖体验 <button id="btn">点击抽奖</button> <script> let btn = document.getElementById('btn'); //随机1~100之间函数 function fun(m,n){ return Math.floor(Math.random() * (n - m) + m) } btn.onclick = function(){ let n = fun(1,100); let p = new Promise((resolve,reject) =>{ if(n<30){ resolve(n); //将promise对象状态设置为【成功】 }else{ reject(n); //将promise对象状态设置为【失败】 } }); p.then(value =>{ console.log('恭喜中奖'+ value +'号'); },reason =>{ console.log('再接再厉'+ reason +'号'); }) } </script>
//promise实现文件读取 // 封装一个函数 mineReadFile 读取文件内容 // 参数:paht 文件路径 // 返回:promise 对象 const fs = require('fs') function mineReadFile(path){ return new Promise((resolve,reject) =>{ //读取文件 fs.readFile(path,(err,data) =>{ //判断 if(err) reject(err); //成功 resolve(data); }); }); }; mineReadFile('./resource/content.txt').then((value =>{ //输出文件内容 console.log(value.toString()); },reason => { console.log(reason.toString()); })) /* util.promisify 方法 引入 util 模块 const util = require('util'); 引入 fs 模块 const fs = require('fs'); 返回一个新的Promise函数 let mineReadFile = util.promisify(fs.readFile); /*
promise封装AJAX // 封装一个函数 sendAJAX 发送 GET AJAX 请求 // 参数 URL // 返回结果 Promise 对象 function sendAJAX(url){ return new Promise((resolve,reject) =>{ var xhr = new XMLHttpRequest(); xhr.open('get',url); xhr.send(); //处理结果 xhr.onreadystatechange = function(){ //判断 if(xhr.readyState == 4){ //判断成功 if(xhr.status >= 200 && xhr.status < 300){ resolve(xhr.response); }else{ reject(xhr.status); }; }; }; }); }; sendAJAX('http://127.0.0.1:8000/ajax-server').then(value =>{ console.log(value); },reason =>{ console.warn(reason); });
六、async 和 await
asycn 函数:
函数的返回值为 promise 对象
promise 对象的结果由 async 函数执行的返回值决定
await 表达式:
await 右侧的表达式一般为 promise 对象,但也可以是其他值
如果表达式是 promise 对象,await 返回的是 promise 成功的值
如果表达式是其他值,直接将此值作为 await 的返回值
注意:
await 必须写在 async 函数中,但async 函数中可以每await
如果 await 的 promise 失败了,就会抛出异常,需要通过 try..cathc 捕获处理
//async 函数 async function main(){ //1.如果返回值是一个非promise类型的数据 return 1; //则reslut会是一个成功的promise对象,值为1 //2.如果返回的是一个promise对象 return new Promise((resolve,reject) => { resolve('ok'); //返回一个成功的promise对象,值为ok reject('error'); //返回一个错误的promise对象,值为error throw "error"; //返回一个错误的promise对象,值为error }) } let result = main(); console.log(result);
async和await结合使用: <button id="btn">点击发送请求</button> <script> function sendAJAX(url){ return new Promise((resolve,reject) =>{ var xhr = new XMLHttpRequest(); xhr.open('get',url); xhr.send(); //处理结果 xhr.onreadystatechange = function(){ //判断 if(xhr.readyState == 4){ //判断成功 if(xhr.status >= 200 && xhr.status < 300){ resolve(xhr.response); }else{ reject(xhr.status); }; }; }; }); }; let btn = document.getElementById('btn'); btn.addEventListener('click',async function(){ let result = await sendAJAX('http://127.0.0.1:8000/ajax-server'); console.log(result); }); </script>