ES6之Promise

什么是Promise

Promise是JavaScript中为解决异步问题,结合社区已有规范,提出的一种异步编程解决方案。 在ES6中,Promise自己一个构造函数,原型链上有then、catch和finally等方法。自身的静态方法有all、race、reject和resolve等。javascript

Promise的三个状态

请求态pending完成态fulfilled拒绝态rejectedjava

一个须要记住的点:git

Promise的状态只能够由 pending ——> fulfilledpending——> rejected,一旦Promise状态发生改变,也就是说一旦Promise的状态变为fulfilled或者rejected,那么它的转态便不可再变。 [image:90230504-F905-4CDC-A4BE-A5FF2FE79F33-4052-0000191F58D20B47/52d29942398343318f015c5b334766a4.png] github

手写一个Promise

(function() {
    function P(fn) {
        var self = this;
        this.fullfilleds = [];
        this.faileds = [];

        function resolve() {
            self.fullfilled = true;
            let args = Array.prototype.slice.call(arguments);

            self.result = args;

            if (self.fullfilleds.length) {
					// 执行then方法注册的函数,真正的操做是将callbacks队列中的回调一一执行
                self.fullfilleds.forEach(fn=>{
                    fn.apply(null, args);
                })
            }
        }

        function reject() {}

        fn.call(null, resolve, reject);
    }

    P.prototype.then = function(fullfilled, failed) {
        if (this.fullfilled) {
            fullfilled.apply(null, this.result)
        } else if (this.failed) {
            failed(this.failed);
        } else {
            this.fullfilleds.push(fullfilled);
            this.faileds.push(failed);
        }
    }

    const p = new P((resolve,reject)=>{
        resolve('sync');
    });

    p.then(d=>{
        console.log(d);
    });

    setTimeout(()=>{
        p.then(d=>{
            console.log(d + 2);
        })
    }, 2000)
}
)()
复制代码

Promise的链式调用

回调地狱

使用回调解决异步编程的方案是一种比较简单直接方式。编程

// demo 1
setTimeout( ()=>{
	console.log("1秒钟后输出");
}, 1000);
// demo 2
Ajax.get('xxx', {}, function(data){
	// DO something
});
复制代码

这种方案单层的回调还算能够,但若是回调里面又出现新的回调,产生嵌套。 像这种app

Ajax.get('xxx', {}, function(){
	Ajax.get('xxx', {}, function(){
		Ajax.get('xxx', {}, function(){
			// do something
		})
	});
})
复制代码

Promise的链式调用则不存在此问题,在能够控制顺序 的前提下,能够比较直观地编写异步代码。异步

异常捕获

在回调函数的方案中,因为回调函数执行栈与原函数分开,致使没法捕获异常。这一点在Promise中,借助rejected,能够将错误捕获。async

调用者主权

不一样于回调函数,Promise借助then方法能够控制程序的执行。若是经过回调函数,调用者是不知道异步程序结束而后调用回调的。异步程序结束后,回回调函数被异步程序本身在后台默默调用,调用者失去了程序的控制权。但Promise中的then方法不存在此问题,由于then方法的调用者仍是主程序自己。ide

Promise跟async/await的关系

简单地说,async/await是Promise的语法糖。由于async函数返回值是Promise类型,await 后面的语句吐出 的是一个Promise传给then方法的数据。异步编程

(async function(){

    async function f(){
        return 1;
    }
    let a = f();
    console.log( a instanceof Promise); // true

    let b = await a;

    console.log(b); // 1

    let c = await Promise.resolve(2);

    console.log(c); // 2
})()
复制代码

async/await仅仅只是Promise的语法糖吗

相对于Promise,在处理 then 的调用链时,async/await的写法可以更清晰准确的写出代码 而且也能优雅地解决回调地狱问题。这更符合人类的线性思惟方式。

【翻译】Promises/A+规范-图灵社区 GitHub - tildeio/rsvp.js: A lightweight library that provides tools for organizing asynchronous code

相关文章
相关标签/搜索