一篇文章带你弄懂Promise(含Promise源码)

Promise是ES6新增一个内置类,可以理解为它是承诺者模式,Promise对象用于表示一个异步操作的最终完成(成功或者失败),以及结果的值。它主要是为了有效管理异步编程,存在的目的就是为了解决回调地狱

什么是回调地狱?

基于ajax的请求,完成需求为请求三个接口(@1:/api/list&@2/api/detail?id=100&@3/api/ranking),带你理解什么是回调地狱。首先先看一段代码:

$.ajax({
        url:'api/list',
        success(){
            // 第一个请求成功,触发了success回调函数
            $.ajax({
                url:'/api/detail?id=100',
                success(){
                    // 第二个请求成功
                    $.ajax({
                        url:'/api/ranking',
                        success(){
                            // 第三请求成功
                        }
                    })
                }
            })
        }
    })

这是ajax的串行:也就是多个请求之间有依赖。只有完成上一个请求,才能发送下一个请求。代码中,代码一层圈套一层。为了实现代码顺序执行而出现的一种操作,它会造成我们的代码可读性非常差,后期不好维护。这就是回调地狱

创建Promise实例的几种方法:
 一:通过new Promise ((executor))      

注意:executor函数执行看是否报错,如果报错则返回是失败的,失败的原因就是报错的原因。但是不报错的不一定成功,它会接着走下一步。

在这里小编对executor函数做一个扩展,帮助你更好的掌握Promise

1. 必须传递的是一个函数,不传或者传递其他类型值都会报错
2. new promise的时候会立即把传递的executor函数执行,这个操作是的同步的.

new Promise(()=>{
console.log(1);
});
console.log(2)
//它的输出结果就是1,2

3. 在executor函数中,一般来写一些易怒的编程代码(promise管理异步编程,其实就是把异步编程的代码放在executor中

[executor]函数中有两个形参:   resolve/reject(本身也都是个函数)

resolve([value])把时刻状态改为fulfilled,实例值是[value]
reject([reason])把实例状态改为rejected,实例值是[reason]
一旦实例状态被改变为成功和失败,不可以再次更改

[executor]函数执行一旦报错,实例的状态也是rejected,实例的值就是报错原因


 二:通过.then实例创建
let @p=实例.then([[onfulfilled]],[[onrejected]])

 在这里说明一下.then和.catch的区别

 .then后面接的是([[onfulfilled]],[[onrejected]])                                     
.catch后面接的是([onjected])  因为catch会对错误进行兜底,就是抛出的任何异常时都会进入到catch中。
then链具备“穿透性”如果onfulfilled或者onrejected没有设置,则会顺延到下一个then对应的onfufilled或者onrejected上!!

三:通过.catch创建
let @p=实例.catch([[onrejected]])

  • @p是执行then/catch返回的新实例 
  • 不论是onfulfilled还是onrejected执行。我们关注的是执行是否报错,返回值来决定@p的状态和值。方法执行只要报错@p就是rejected,值就是报错的原因,返回值不是一个新的promise实例,则@p就是fulfilled值就是返回结果。如果返回的是一个新的promise实例(@new)则@new的状态和值决定了@p的状态和值
  • 如果两个方法中的某个方法没有传递,则"顺延"到下一个[then的穿透机制]

四:创建一个状态为成功的promise实例(fulfilled)
Promise.resolve([[value]])
创建一个状态为失败的promise实例(rejected)
Promise.resolve([[reason]])
Promise.all([[paomise]])
创建一个实例,当[[promises]]当集合中的每一项实例都是成功,最后整体返回的就是成功(值:按照顺序,储存了集合中每一项成功的结果)其中只要又一项是失败的,整体返回就是失败的(值:谁失败,获取的结果就是谁失败的原因,只要有一项失败了,则处理结果就结束了)


五:还有许多创建Promise的方法
Promise.race/any...

前面是关于一些创建Promise的一些基础知识,了解过基础知识,接下来就跟着小编去看一些源码,来帮助你更深层次的掌握Promise

目录

创建Promise实例的几种方法: 一:通过new Promise ((executor))      

源码部分

  


源码部分

// 首先为了防止冲突,将promise源码采用闭包的形式保护起来
    (function () {
    /* 核心 */
    function Promise(executor) {
    // 对Promise进行检测,检测executor是不是一个函数以及检测Promise是不是一个实例
        var self = this;
        if (typeof executor !== "function") throw new TypeError("Promise resolver is not a function");
        if (!(self instanceof Promise)) throw new TypeError("undefined is not a promise");
        // 给Promise 设置私有属性
        self.state = "pending";
        self.result = undefined;
        self.onfulfilledCallback = [];
        self.onrejectedCallback = [];
        var change = function change(state, result) {
            // 修改实例的状态和值(同步) & 通知集合中指定的方法执行(异步)
            if (self.state !== "pending") return;
            self.state = state;
            self.result = result;
            setTimeout(function () {
                var callback = state === "fulfilled" ? self.onfulfilledCallback : self.onrejectedCallback;
                for (var i = 0; i < callback.length; i++) {
                    callback[i](self.result);
                }
            });
        };
        // 立即执行executor函数
        try {
            executor(function resolve(value) {
                change('fulfilled', value);
            }, function reject(reason) {
                change('rejected', reason);
            });
        } catch (err) {
            change('rejected', err);
        }
    }
    Promise.prototype = {
        constructor: Promise,
        then: function then(onfulfilled, onrejected) {
            var self = this;
            switch (self.state) {
                case "fulfilled":
                    setTimeout(function () {
                        onfulfilled(self.result);
                    });
                    break;
                case "rejected":
                    setTimeout(function () {
                        onrejected(self.result);
                    });
                    break;
                default:
                    self.onfulfilledCallback.push(onfulfilled);
                    self.onrejectedCallback.push(onrejected);
            }
        },
        catch: function myCatch() { }//注意catch这里命名方式,遵循js中的命名规范
    };
    // 暴露API:即支持CommonJS模块规范也支持浏览器直接导入 >处理兼容问题
    if (typeof module === "object" && typeof module.exports === "object") module.exports = Promise;
    if (typeof window !== "undefined") window.Promise = Promise;
})();
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值