概念
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。Promise 是异步编程的一种解决方案,主要用来解决回调地狱的问题,可以有效的减少回调嵌套。真正解决需要配合async/await。
特点:
(1)对象的状态不受外界影响。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。
缺点:
(1)无法取消Promise,一旦新建它就会立即执行,无法中途取消。和一般的对象不一样,无需调用。
(2)如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
(3)当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
代码体验
抽奖功能
代码:
<body> <div><button id="btn">点击抽奖</button></div> <script> //生成随机数 function rand(m, n) { return Math.ceil(Math.random() * (n - m + 1)) + m - 1; } //获取元素对象 const btn = document.querySelector('#btn'); //绑定单击事件 btn.addEventListener('click', function () { //定时器 // setTimeout(() => { // let n = rand(1, 100); // if (n <= 30) { // alert('喜报~~~~奖品为 劳斯莱斯 一辆!'); // } else { // alert('再接再厉'); // } // }, 1000); //promise形式实现,resolve解决(成功调用),reject拒绝(失败调用)(两个都是函数类型的数据) const p = new Promise((resolve,reject)=>{ setTimeout(()=>{ let n = rand(1,100) if(n<=70){ resolve() }else{ reject() } },500) }) console.log(p,"promise") p.then(()=>{ alert('喜报~~~~奖品为 劳斯莱斯 一辆!'); //这个回调函数是成功的 },()=>{ alert('再接再厉');//这个回调函数是失败的 }) }) </script> </body>
讯享网
pormise基本流程

为什么要用promise?
1、链式调用,解决回调地狱问题
2、给promise对象绑定回调函数,可以再异步任务结束后指定多个
回调地狱怎么解决?
promise链式调用,用promise加上await和async关键字来实现异步传同步
如何使用Promise?
不属于new Promise的API(4个)
1、Promise.resolve方法:(value)=>{}
value:成功的数据或promise对象
说明:返回一个成功/失败的promise对象
2、Promise.reject方法:(reason)=>{}
reason:失败原因

说明:返回一个失败的promise对象
3、Promise.all方法:(promises)=>{}
promises:包含n个promise的数组
说明:返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就 直接失败
4、Promise.race方法:(promises)=>{}
promises:包含n个promise的数组
说明:返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态
自定义(手写)Promise

如何让状态只执行一次?

then方法执行回调

异步任务then方法实现
图一

图二

指定多个回调



同步任务then方法返回结果

异步任务then方法返回结果

整体封装好的代码
讯享网class Promise{ //构造方法 constructor(executor){ //添加属性 this.PromiseState = 'pending'; this.PromiseResult = null; //声明属性 this.callbacks = []; //保存实例对象的 this 的值 const self = this;// self _this that //resolve 函数 function resolve(data){ //判断状态 if(self.PromiseState !== 'pending') return; //1. 修改对象的状态 (promiseState) self.PromiseState = 'fulfilled';// resolved //2. 设置对象结果值 (promiseResult) self.PromiseResult = data; //调用成功的回调函数 setTimeout(() => { self.callbacks.forEach(item => { item.onResolved(data); }); }); } //reject 函数 function reject(data){ //判断状态 if(self.PromiseState !== 'pending') return; //1. 修改对象的状态 (promiseState) self.PromiseState = 'rejected';// //2. 设置对象结果值 (promiseResult) self.PromiseResult = data; //执行失败的回调 setTimeout(() => { self.callbacks.forEach(item => { item.onRejected(data); }); }); } try{ //同步调用『执行器函数』 executor(resolve, reject); }catch(e){ //修改 promise 对象状态为『失败』 reject(e); } } //then 方法封装 then(onResolved,onRejected){ const self = this; //判断回调函数参数 if(typeof onRejected !== 'function'){ onRejected = reason => { throw reason; } } if(typeof onResolved !== 'function'){ onResolved = value => value; //value => { return value}; } return new Promise((resolve, reject) => { //封装函数 function callback(type){ try{ //获取回调函数的执行结果 let result = type(self.PromiseResult); //判断 if(result instanceof Promise){ //如果是 Promise 类型的对象 result.then(v => { resolve(v); }, r=>{ reject(r); }) }else{ //结果的对象状态为『成功』 resolve(result); } }catch(e){ reject(e); } } //调用回调函数 PromiseState if(this.PromiseState === 'fulfilled'){ setTimeout(() => { callback(onResolved); }); } if(this.PromiseState === 'rejected'){ setTimeout(() => { callback(onRejected); }); } //判断 pending 状态 if(this.PromiseState === 'pending'){ //保存回调函数 this.callbacks.push({ onResolved: function(){ callback(onResolved); }, onRejected: function(){ callback(onRejected); } }); } }) } //catch 方法 catch(onRejected){ return this.then(undefined, onRejected); } //添加 resolve 方法 static resolve(value){ //返回promise对象 return new Promise((resolve, reject) => { if(value instanceof Promise){ value.then(v=>{ resolve(v); }, r=>{ reject(r); }) }else{ //状态设置为成功 resolve(value); } }); } //添加 reject 方法 static reject(reason){ return new Promise((resolve, reject)=>{ reject(reason); }); } //添加 all 方法 static all(promises){ //返回结果为promise对象 return new Promise((resolve, reject) => { //声明变量 let count = 0; let arr = []; //遍历 for(let i=0;i<promises.length;i++){ // promises[i].then(v => { //得知对象的状态是成功 //每个promise对象 都成功 count++; //将当前promise对象成功的结果 存入到数组中 arr[i] = v; //判断 if(count === promises.length){ //修改状态 resolve(arr); } }, r => { reject(r); }); } }); } //添加 race 方法 static race (promises){ return new Promise((resolve, reject) => { for(let i=0;i<promises.length;i++){ promises[i].then(v => { //修改返回对象的状态为 『成功』 resolve(v); },r=>{ //修改返回对象的状态为 『失败』 reject(r); }) } }); } }
async函数与await表达式
1、async
- 使用async函数的返回值为 Promise对象
- Promise对象的结果由async函数执行的返回值决定
async function main1() { //1. 如果返回值是一个非Promise类型的数据 则状态为成功,返回一个成功的promise对象 return 521; } async function main2() { //2. 如果返回的是一个Promise对象 则状态取决于返回结果 return new Promise((resolve, reject) => { // resolve('OK'); //成功 reject("Error"); //失败 }); } async function main3() { // 3. 抛出异常 返回一个失败的promise对象 throw "出错啦"; } let result1 = main1(); let result2 = main2(); let result3 = main3(); console.log(result1); console.log(result2); console.log(result3);
2、await 表达式
- await右侧表达式一般为promise对象,但也可以使其他的
- 如果表达式是promise对象,await返回的是promise成功的值
- 如果表达式是其他值,直接将此值作为await的返回值
- 注意
- await必须写在async函数中,但async函数中可以没有await
- 如果await的promise失败了,就会抛出异常,需要try...catch捕获处理
讯享网
async function main() { let p = new Promise((resolve, reject) => { // resolve("OK"); reject("Error"); try { let res3 = await p; console.log(res3) } catch (e) { //catch捕获失败状态 console.log(e); } } main();

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/126117.html