promise

相信大家对这个是挺熟悉的了吧,毕竟都会用到异步函数,这个其实还好,不打算长篇大论的叙述了,简单的说下。 他有在执行(pending)的时候,有个简短的生命周期,在pending的时候可以叫做unsettled, 当promise执行结束之后,会变成settled,settled主要是有下面两种状态

  • Fulfilled: promise成功完成.

  • Rejected: promise未能完成,失败或者其他情况下产生.

并且promise有个内部的属性[[PromiseState]],他的值只有这三种pending, fulfilled, rejected.这个属性是不对外暴露的,导致编程时不能确定他的状态,但是可以通过then来确定.

then方法接受两个参数,第一个是成功的回调函数,第二个是失败时候的回调函数

所有方法根据这个来生成then()方法的都被称之为thenable.所有的promise都是thenable的,但并非所有的thenable都是promise.

thenable = {
    then: function(resolve, reject) {
        resolve(42);
    }
};

p1 = Promise.resolve(thenable);
p2 = Promise.reject(thenable)
p1.then(function(value) {
    console.log(value);     // 42
});

p2.then(i => console.log('in work'), (err) => console.log('is error'))

下面来看看操作多个promise的。all,没错,就是他。

Promise.all()接受一个参数,这个参数是可迭代的,并且返回的是在迭代中被成功处理的。而且这些返回的值是按照传递的顺序存储的。

p1 = new Promise(function(resolve, reject) {
    resolve(42);
});
p2 = new Promise(function(resolve, reject) {
    resolve(43);
});
p3 = new Promise(function(resolve, reject) {
    resolve(44);
});
p4 = Promise.all([p1, p2, p3]);
p4.then(function(value) {
    console.log(Array.isArray(value));  // true
    console.log('here value is', value) // here value is (3) [42, 43, 44]
    console.log(value[0]);              // 42
    console.log(value[1]);              // 43
    console.log(value[2]);              // 44
});

all()存在失败的情况就会立即返回,不会等待其他的完成,看下面例子:

p1 = new Promise(function(resolve, reject) {
    resolve(42);
});
p2 = new Promise(function(resolve, reject) {
    reject(43);
});
p3 = new Promise(function(resolve, reject) {
    resolve(44);
});
p4 = Promise.all([p1, p2, p3]);
p4.catch(function(value) {
    console.log(Array.isArray(value))   // false
    console.log(value);                 // 43
});

all()相对的就是race方法,他传参和all差不多,不过返回的机制却是不同。 race是当有一个完成就会返回,而不是等待其他的也完成。 race只会关心第一个返回settled的结果,如果是Fulfilled,那么返回的结果就是Fulfilled,如果是rejected,那么返回的结果就是rejected.

p1 = new Promise(function(resolve, reject) {
    setTimeout(function() {
        resolve(42);
    }, 100);
});
p2 = new Promise(function(resolve, reject) {
    reject(43);
});
p3 = new Promise(function(resolve, reject) {
    setTimeout(function() {
        resolve(44);
    }, 50);
});
p4 = Promise.race([p1, p2, p3]);
p4.catch(function(value) {
    console.log(value);     // 43
});

继承自promise

class MyPromise extends Promise {

    // use default constructor

    success(resolve, reject) {
        return this.then(resolve, reject);
    }

    failure(reject) {
        return this.catch(reject);
    }

}

let promise = new MyPromise(function(resolve, reject) {
    resolve(42);
});

promise.success(function(value) {
    console.log(value);             // 42
}).failure(function(value) {
    console.log(value);
});

在这里,他继承了promise的所有内置方法。但是略有不同,比如静态方法有四个Promise.resolve(), Promise.reject(), Promise.all(), Promise.race(),最后两个静态方法和内置方法的行为相同,但是前面两个方法略有不同。

无论传递的值如何,MyPromise.resolve()MyPromise.reject()都将返回MyPromise的实例,因为这些方法使用Symbol.species属性(之前一文有介绍)来确定要返回的promise的类型。

p1 = new Promise(function(resolve, reject) {
    resolve(42);
});

p2 = MyPromise.resolve(p1);
p2.success(function(value) {
    console.log(value);         // 42
});

console.log(p2 instanceof MyPromise);   // true

有些人会说async,但是他最终是在ECMAScript 2017 (ECMAScript 8)出的。

Last updated