谈谈Promise

首先看一段代码


    setTimeout(function(){
        console.log(1)
    }, 3000)
    setTimeout(function(){
        console.log(2)
    }, 2000)
    setTimeout(function(){
        console.log(3)
    }, 1000)
        

此时会输出 3 2 1, 原本我们是想输出 1 2 3 的,但是在异步的情况下,我们没办法改变异步的顺序,这是我们可以用回调函数来控制顺序,但是又有一个扎心的问题 -- 回调地狱

这时我们的promise就出场啦,代码改为:


    new Promise(function(resolve, reject){
        setTimeout(function(){
            console.log(1)
            resolve()
        }, 3000)
    })
    .then(function(data){
        return new Promise(function(resolve, reject){
            setTimeout(function(){
                console.log(2)
                resolve()
            }, 2000)
        })
    })
    .then(function(data){
        return new Promise(function(resolve, reject){
            setTimeout(function () {
                console.log(3)
                resolve()
            }, 1000)
        })
    })

在浏览器预览: 隔3秒输出1,再隔2秒输出2,再隔1秒输出3

这样就符合我们预期的想法了

来看看代码, 先new一下 证明我们第一步应该创建构造函数 Promise(callback) ,接着后面有 then(fn) ,于是我们可以断定 Promise.prototype.then = fn() {} , 于是根据执行情况,我们可以把执行顺序捋一捋

Promise -> 接收的函数立即执行 -> then(fn) (保存参数函数) -> resolve() -> then内部的回调函数

我们再来看看,promomise里面有resolve和reject 那就可以看出promise有两种状态,但这两种只是判断成功或者失败,所以我们还需要一个初始状态。 故: pending / fulfilled / rejected 这三种状态

接着看代码,看着注释,就可以大致明白啦

var PENDING = 'PENDING';
var FULFILLED = 'FULFILLED';
var REJECTED = 'REJECTED';

// 1: 构造函数Promise
function Promise(fn) {
    // 2. 构造函数内初始 状态Pending 和 value
    this.status = PENDING; // 状态是待发状态
    this.value = null;  // 初始值
    this.deffered = []; // 下一个 要执行的Promise是谁,子promise

    // 3.构造函数内调用函数(apply参数是数组,call参数是一个个,调用函数改变this指向, bind不会立即调用,只是改变this)
    fn.call(this, this.resolve.bind(this), this.reject.bind(this));

}

// 4. 结束回调函数, 执行then Promise.prototype.then 是函数
// 5. then函数内不需要保存起成果或者失败的函数
Promise.prototype = {
    constructor: Promise, // 改变回来原型链
    then: function(onfulfilled, onrejected) {
        // 保存该函数
        var obj = {
            onfulfilled: onfulfilled,
            onrejected: onrejected
        }

        // 新来一个Promise对象,让其存储这些
        // 并且能根据不同的Promise去then
        obj.promise = new this.constructor(function(){});
        
        // 保存起接下来的promise
        // console.log(this)
        // console.log(obj.promise)

        // 建立上一个与下一个primise之间的关系
        if(this.status === PENDING) {
           this.deffered.push(obj); 
        }

        // 保证不报错, 未来不能return自己  需要换人
        return obj.promise; // 下一个then的哥们

    },
    
    // 定义成功和失败的回调函数, 改变状态, 记录数据结果, 执行后续的行为
    resolve: function(data) {
        this.status = FULFILLED;
        this.value = data;
        // 执行后续的行为
        this.done();
    },
    reject: function(err) {
        this.status = REJECTED;
        this.value = err;
        // 执行后续的行为
        this.done();
    },
    // 执行后续的行为
    done: function() {
        // 让这些this.deffered(子promise得到执行)
        this.deffered.forEach(task => this.handler(task));

    },
    handler: function(task) {   
        // 判断当前执行的状态是怎样, 调用对应的函数
        var status = this.status;
        var value = this.value;
        var p;
        switch(status) {
            case FULFILLED: 
                p = task.onfulfilled(value);
                break;
            case REJECTED:
                p = task.onrejected(value);
                break;
        }

        // 如果 p是一个promise的话,我们需要让他们继续执行
        // 把后续(task.promise)的deffer 交给这个p
        if(p && p.constructor === Promise) {
            // 是一个promise
            // 把下一个作为then链接的deffer 移交给deffered
            p.deffered = task.promise.deffered;
        }
    },
}



我们按照思路先写一个demo

var PENDING = 'PENDING'
var FULFILLED = 'FULFILLED'
var REJECTED = 'REJECTED'

// 1 构造函数Promise
function Promise(fn) {
    this.status = PENDING;  // 初始化状态
    // 2 构造函数内调用函数 
    this.value = null;  // 初始值
    this.deffered = [];  // 下一个执行的Promise执行是谁
    // 3 构造函数内初始 状态Pending 和 value
    fn()
}

// 4 结束回调函数后执行then -> Promise.prototype.then 是函数
// 5 then函数内部需要保存起成功或者失败的函数
Promise.protope = {
    //  定义成功和失败的回调函数,改变状态,记录数据结果, 执行后续的行为
    resolve: function(data) {
        this.status = FULFILLED;
         this.value = dat
    },
    constructor: Promise,  // 改变回来原型链
    then: function() {

    }

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容

  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 8,702评论 1 56
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 11,025评论 26 95
  • 本文适用的读者 本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,...
    HZ充电大喵阅读 7,299评论 6 19
  • 这个很早以前写的,今天看群里有人问关于promise的问题,在这里重新发一下。偷懒的同学可以直接拉到最后有完整的代...
    grain先森阅读 2,912评论 1 9
  • 《从优秀到卓越》是美国作者吉姆柯林斯《基业长青》之后的又一力作。它描绘了优秀公司实现向卓越公司跨越的宏伟蓝图。在本...
    HiSwallow阅读 830评论 0 0