Promise学习笔记-五(Promise静态方法)

487 阅读4分钟

创建未处理的Promise的最好方法是使用Promise的构造函数,如果只想用Promise表示一个已知的值,编排一个只是简单的给resolve()函数传值的任务毫无意义,有什么替代方案吗?在实际工作中,会遇到编排很多任务依次执行完成之后,对每次执行结果处理,显然会很繁琐。可不可以所有的编排任务,一次被得到响应,然后再对结果做最终处理呢?Promise提供的四个静态方法可以满足以上两个场景下的需求,进而增加代码的可读性。

创建已处理的Promise

如果只想用Promise表示一个已知的值,编排一个只是简单的给resolve()reject()传值的任务显得有点不合事宜。可以用以下两种方法根据特定的值来创建已解决Promise。

  • 使用Promise.resolve()

    Promise.resolve()方法只接受一个参数并返回一个完成态的Promise,也就是说不会有任务编排的过程,而且需要项Promise添加一至多个完成处理程序来获取值。例如:

    let promsie = Promise.resolve(42)
    promise.then(function (value) {
        console.log(value) // 42
    })
    
  • 使用Promise.reject()

    Promise.reject()创建已拒绝Promise,它与Promise.resolve()唯一的区别是创建出来的是拒绝态的Promise。例如:

    let promise = Promise.reject(34)
    promise.catch(function (value) {
        console.log(value) // 43
    })
    

Promise.resolve源码

var TRUE = valuePromise(true);
var FALSE = valuePromise(false);
var NULL = valuePromise(null);
var UNDEFINED = valuePromise(undefined);
var ZERO = valuePromise(0);
var EMPTYSTRING = valuePromise('');

function valuePromise (value) {
    var p = new Promise(Promise._noop)
    p._state = 1
    p._value = value
    return p
}
Promsie.resolve = function (value) {
    // 传入的是Promise对象时,会被直接返回
    if (value instanceof Promise) return value
    // 传入以下数据类型时,需要调用valuePromise方法返回一个Promise对象
    if (value === null) return NULL
    if (value === undefined) return UNDEFINED
    if (value === true) return TRUE
    if (value === false) return FALSE
    if (value === 0) return ZERO
    if (value === '') return EMPTYSTRING
    // value为object或function时
    if (typeof value === 'object' || typeof value === 'function') {
        try {
            var then = value.then
            if (typeof then === 'function') {
                return new Promise(then.bind(value))
            } catch (ex) {
                return new Promise(function (resolve, reject) {
                    reject(ex)
                })
            }
        }
        // 以上条件都不符合
        return valuePromise(value)
    }
}
  • 如果向Promise.resolve()Promise.reject()传入一个Promise,通过 if (value instanceof Promise) return value直接返回Promise对象。
  • 传入一个非Promisse的Thenable对象,这些方法会创建一个新的Promise对象,并在then()函数中被调用。传入一个非Promise的Thenable对象时,经过typeof value === 'object' || typeof value === 'function'判断,返回一个新的Promise对象,并将Thenable对象的then()方法作为参数传到新实例化的Promise对象中。举个栗子:
let thenable = {
    then: function (resolve, reject) {
        resolve('我是thenable对象的输出')
    }
}
let p1 = Promise.resolve(thenable)
p1.then(function (value) {
    console.log(value) // 我是thenable对象的输出
})

在此示例中,thenable对象作为参数传入时,其实就转化为p1 = new Promise(function (resolve, reject) {resolve(''我是thenable对象的输出'')}),因此最后结果输出“'我是thenable对象的输出'”。

Promise.reject源码

Promise.reject的实现过程相对来说简单,只是返回一个Promise实例对象。代码如下:

Promise.reject = function (value) {
    return new Promise(function (resolve, reject) {
        reject(value)
    })
}

响应多个Promise

ECMAScript6提供了Promise.all()Promise.race()两个方法监听多个Promise。

Promise.all

Promise.all()方法只接受一个参数并返回一个Promise,该参数是一个含有多个受监视Promise的可迭代对象,只有当可迭代对象中所有的Promise都被解决后返回的Promise才会被解决;只有当可迭代对象中所有Promise都被接完成后返回的Promise才会被完成。

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

所有传入Promise.all()方法的Promise只要有一个被拒绝,那么返回的Promise没等所有Promise都完成就立即被拒绝。例如:

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

Promise.race

Promise.race()方法接受一个含多个受监视Promise的可迭代对象作为唯一参数并返回一个Promise,但只要有一个Promise被解决返回的Promise就被解决,无须等到所有Promise都被完成,例如:

let p1 = Promise.resolve(34)
let p2 = new Promise(function (resolve, reject) {
    resolve(35)
})
let p3 = new Promise(function (resolve, reject) {
    resolve(36)
})
let p4 = Promise.race([p1, p2, p3])
p4.then(function (value) {
    console.log(value) // 34
})

传给Promise.race()方法的Promise会进行竞选,以决出哪一个先被解决,如果先解决的是已完成Promise,则返回已完成Promise;如果先解决的是已拒绝Promise,则返回已拒绝Promise。例如:

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