zoukankan      html  css  js  c++  java
  • promise

    什么是Promise?

    Promise可以简单理解为一个事物,这个事物存在三种状态:

    1. 已经完成了 resolved
    2. 因为某种原因被中断了 rejected
    3. 还在等待上一个事务结束 pending

    Promise 就是一个事务的管理器。他的作用就是将各种内嵌回调的事务用流水形式表达,其目的是为了简化编程,让代码逻辑更加清晰。

     
    Promise是一个构造函数,自身有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法,用Promise new出来的对象肯定就有then、catch方法了
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
            console.log('执行完成');
            resolve('123');
        }, 2000);
    });
    Promise的构造函数接收一个参数,是函数,这个函数接收两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。resolve是将Promise的状态置为resolved,reject是将Promise的状态置为rejected。
     
    在上面的代码中,我们执行了一个异步操作,也就是setTimeout,2秒后,输出“执行完成”,并且调用resolve方法。
     
    运行代码,会在2秒后输出“执行完成”。注意!我只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,这是需要注意的一个细节。所以我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数:
    function runAsync(){
        var p = new Promise(function(resolve, reject){
            //做一些异步操作
            setTimeout(function(){
                console.log('执行完成');
                resolve('123');
            }, 2000);
        });
        return p;            
    } 
    runAsync() 

    在操作事务之前,我们会先把各种事务依次放入事务队列中,这里会用到 then 方法:

    Promise.prototype.then = function (nextAffair){
        var promise = new Promise();
        if (this.state == ‘resloved’){
            // 如果当前状态是已完成,则这个事务将会被立即执行
            return this._fire(promise, nextAffair);
        }else{
            // 否则将会被加入队列中
            return this._push(promise, nextAffair);
        }
    };

    如果整个操作已经完成了,那 then 方法送进的事务会被立即执行,

    Promise.prototype._fire = function (nextPromise, nextAffair){
        var nextResult = nextAffair(this.result);
        if (nextResult instanceof Promise){
            nextResult.then(function(obj){
                nextPromise.resolve(obj);
            });
        }else{
            nextPromise.resolve(nextResult);
        }
        return nextPromise;
    };
    被立即执行之后会返回一个结果,这个结果会被传递到下一个事务中作为原料,但是这里需要考虑两种情况:
    1. 异步,如果这个结果也是一个 Promise,则需要等待这个 Promise 执行完毕再将最终的结果传到下一个事务中。
    2. 同步,如果这个结果不是 Promise,则直接将结果传递给下一个事务。

    第一种情况还是比较常见的,比如我们在一个事务中有一个子事务队列需要处理,此时必须等待子事务完成才能回到主事务队列中。

    Promise.prototype.resolve = function (obj){
        if (this.state != ‘pending’) {
            throw ‘流程已完成,不能再次开启流程!’;
        }
        this.state = ‘resloved’;
        // 执行该事务,并将执行结果寄存到 Promise
        this.result = this.affair(obj);
        for (var i = 0, len = this.allAffairs.length; i < len; ++i){
            // 往后执行事务
            var affair = this.allAffairs[i];
            this._fire(affair.promise, affair.affair);
        }
        return this;
    };

    resolve 接受一个参数,这个数据是交给第一个事务来处理的,因为第一个事务的启动可能需要数据,它也可以是空。该事物处理完毕之后,将操作结果(result)寄存在 Promise 对象上,方便引用,然后将结果(result)作为原料送入下一个事务。

    我们看到 then 方法中还调用了一个 _push ,这个方法的作用是将事务推进事务管理器(Promise)。

    Promise.prototype._push = function (nextPromise, nextAffair){
        this.allAffairs.push({
            promise: nextPromise,
            affair: nextAffair
        });
        return nextPromise;
    };

    以上操作,我们就实现了一个简单的事务管理器

  • 相关阅读:
    昨天晚上简单英文词典查询及排版系统写完了
    c函数 atoi() 将字符串转换为整型 kbhit() 检测是否有按键按下 区分bioskey()
    写了一个字典树
    用scanf清空缓冲区 对比fflush
    爬取千千小说 -- xpath
    第二十六篇 -- 去掉标题栏并自定义标题栏
    git clone 中途停止不动
    使用turtle库画一朵玫瑰花带文字
    正则爬取我要个性网的头像
    用Pygal画一个英雄能力的图
  • 原文地址:https://www.cnblogs.com/SF9924/p/14175114.html
Copyright © 2011-2022 走看看