Promise(1)

Promise

promise介绍

Promise是ES6异步编程的解决方案,构造函数;
异步编程包括:fs文件操作、数据库操作、AJAX、定时器

优势:
  1. 支持链式调用,解决回调地狱;
//e.g.回调地狱,不便于阅读和异常处理
asyFunc1(opt,(...args1)=>{
	asyFunc2(opt,(...args2)=>{
		asyFunc1(opt,(...args3)=>{
			asyFunc1(opt,(...args4)=>{
			//some opertation
			});
		});
	});
})
  • promise指定回调的方式更为灵活:启动异步任务=>返回promise对象=>给promise对象绑定回调函数。
状态: PromiseState

实例对象的属性:

  • pending 等待中,未得到结果
  • resolved/ fullfilled 成功
  • rejected 失败

变换方式pending—>resolved 或者 pending—>rejected
状态只能改变一次,不可逆。成功的结果称为value,失败称为reason

new Promise(function(resolve, reject) {
    if(true) { resolve() };
    if(false) { reject() };
});

其中,resolvereject都是函数,他们的作用是分别将状态修改成resolvedrejected
此外,还可以通过throw""来改变状态为rejected,抛出异常。

对象的值: PromiseResult

存储异步任务成功或者失败的结果

  • resolve
  • reject
    在这里插入图片描述
API
  1. Promise构造函数:Promise(excutor){}excutor会在Promise内部立刻同步调用,异步在执行器中执行。
new Promise((resolve, reject) => {
            resolve(4);
            setTimeout(() => {
                console.log(1);
            }, 1000);
            console.log(2);
        }).then((value) => {
            console.log(value);
        });
        console.log(3);
//结果为2,3,4,1
  1. Promise.prototype.then方法:(onResolved, onRejected)=>{}
  2. Promise.prototype.catch方法:(onRejected)=>{}用来指定失败的回调。
new Promise((resolve, reject) => {
            reject("err");
        }).catch(reason => {
            console.log(reason)
        });
//结果为err
  1. Promise.resolve方法: (value) => {},返回一个成功或者失败的promise对象;如果传入的参数是非promise类型的对象,返回成功的promise对象;如果传入promise对象,则参数的对象决定了其结果。
        let p1 = Promise.resolve(123);
        console.log(p1);
        let p2 = Promise.resolve(new Promise((resolve, reject) => {
            resolve("ok");
        }));
        console.log(p2);

在这里插入图片描述

  1. Promise.reject方法: (reason) => {},无论传入类型为什么,返回失败的对象。
let p1 = Promise.reject(123);
console.log(p1);

在这里插入图片描述

  1. Promise.all()方法:返回一个新的promise,只有所有的promise都成功才成功,只要一个失败了就直接失败。
  2. Promise.race()方法:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态。
  3. 如果为一个promise对象指定多个成功或失败的回调函数(.then)。如果状态改变,那么对应的回调就都会执行;反之,如果是pending状态,就都不会执行。
案例

需求:点击按钮,2s后显示是否中奖(30%概率中奖),若中奖弹出,“恭喜中奖”;否则,“再接再厉”。
原来:

<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);
                // let n = 50;
                if (n <= 30) {
                    alert("恭喜中奖");
                }
                else {
                    alert("再接再厲");
                }
            }, 1000);
        })
    </script>
</body>

这里解释一下HTML的DOM querySelector()方法document.querySelector("#btn")返回匹配指定选择器的第一个元素,此处获取文档中id是btn的对象元素。

改用promise:
包裹异步操作,then处理成功和失败的结果。

        btn.addEventListener('click', function () {
            const p = new Promise((resolve, reject) => {
                setTimeout(() => {
                    let n = rand(1, 100);
                    // let n = 80;
                    if (n <= 30) {
                        resolve();
                    }
                    else {
                        reject();
                    }
                }, 1000);
            }).then(() => {
                alert("恭喜中奖");

            }, () => {
                alert("再接再厲");

            })
        })

改进呈现随机得到的数字n:

        btn.addEventListener('click', function () {
            const p = new Promise((resolve, reject) => {
                setTimeout(() => {
                    let n = rand(1, 100);
                    // let n = 80;
                    if (n <= 30) {
                        resolve(n);
                    }
                    else {
                        reject(n);
                    }
                }, 1000);
            }).then((value) => {
                alert("恭喜中奖,数字为:" + value);

            }, (reason) => {
                alert("再接再厲,数字为:" + reason);

            })
        });
  • util.promisify

采用遵循常见的错误优先的回调风格的函数(也就是将 (err, value) => ...回调作为最后一个参数),并返回一个返回 promise 的版本。

const util = require('util');
const fs = require('fs');

const stat = util.promisify(fs.stat);
stat('.').then((stats) => {
  // 使用 `stats` 做些事情
}).catch((error) => {
  // 处理错误。
});
问:
  1. 改变promise状态和指定回调函数谁先谁后?【指定不是执行】
    都有可能;在执行器中直接调用resolve()或者reject()实现改变状态再指定回调;如果执行器延长更长时间,例如,setTimeout(()=>{resolve("444");},1000);时先调用then
  2. .then返回的结果由什么决定。如下:
        let p = new Promise((resolve, reject) => {
            resolve("ok");
        });
        let result = p.then(value => {
            // 1.抛出错误,返回rejected
            // throw "err";
            // 2.返回非promise对象,返回状态成功,且结果为输入
            // return 123;
            // 返回promise对象,结果和状态示其返回结果而定
            return new Promise((resolve, reject) => {
                reject("123");
            })
        }, reason => {
            console.warn(reason);
        });
        console.log(result);
  1. 串联多个任务
 let p = new Promise((resolve, reject) => {
            resolve("ok");
        });
        p.then(value => {
            return new Promise((resolve, reject) => {
                resolve("success")
            })
        }, reason => {
            console.warn(reason);
        }).then(value => {
            console.log(value)
        }).then(value => {
            console.log(value)
        });
        //结果为success和undefined,因为没有前一个返回没有调用resolve,前一个返回一个成功的promise,结果是undefined。
  1. 异常穿透:在最后加.catch实现对上述串联任务的错误处理。
  2. 中断promise链:返回一个pending状态的promise对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值