Promise.resolve() 和 Promise.reject()
Promise 构造函数的两个静态方法 resolve 和 reject 可以方便的创建 已解决 的 Promise 实例。
有时候,当我们需要传递一个 promise 类型值,并且 实际值 已知的情况,使用 Promise.resolve() 和 Promise.reject() 方法来包装 实际值 , 这比起使用 new Promise() , 再传入一个总是返回固定值的匿名函数要简单的多。
不过,这两个方法在行为方面有些不一样,例如 resolve 方法接收一个 promise 作为参数时,并不会把这个 promise 再包装成新的 promise ,而是直接返回这个参数。如下:
let p_resolve = Promise.resolve('#1'); // 创建“完成态”的 promise let p_reject = Promise.reject('#2'); // 创建“拒绝态”的 promise let p_pendding = new Promise(() => '#3'); // 创建“处理中”的 promise // 测试用例 console.log(Promise.resolve(p_resolve) === p_resolve); // true console.log(Promise.resolve(p_reject) === p_reject); // true console.log(Promise.resolve(p_pendding) === p_pendding); // true
所以 resolve 方法返回的 promise 并不总是 “完成态” 的。
reject 方法的行为和 resolve 不同,当传入 reject 方法的参数是 promise 类型值的时候,返回值总是一个新的 promise 实例,且这个 promise 是 拒绝态 的,实际值 则是传入的那个 promise 。
这意味着 reject 方法并不会像 resolve 方法那样区别对待传入的值,而是“一视同仁”。如下:
let p_resolve = Promise.resolve('#1'); // 创建“完成态”的 promise let p_reject = Promise.reject('#2'); // 创建“拒绝态”的 promise let p_pendding = new Promise(() => '#3'); // 创建“处理中”的 promise // 测试用例1 console.log(Promise.reject(p_resolve) === p_resolve); // false console.log(Promise.reject(p_reject) === p_reject); // false console.log(Promise.reject(p_pendding) === p_pendding); // false // 打印实际值和期望值是否一样 let print = (expected, actual) => console.log(expected === actual); // 测试用例2 Promise.reject(p_resolve).catch(print.bind(null, p_resolve)); // true Promise.reject(p_reject).catch(print.bind(null, p_reject)); // true Promise.reject(p_pendding).catch(print.bind(null, p_pendding)); // true
对于 thenable 对象,reject 方法也一样不会特殊处理,而是和其他普通值一样,将其包装成新的 promise 对象。resolve 方法则会去处理 thenable 对象。如下:
let thenable = { then: (resolve) => { resolve('#1') } } // 打印实际值和期望值是否一样 let print = (expected, actual) => console.log(expected === actual); Promise.reject(thenable).catch(print.bind(null, thenable)); // true Promise.resolve(thenable).then(print.bind(null, '#1')); // true
对 reject 方法来说,传入 thenable 对象和传入一个普通值没什么两样。
而对 resolve 方法来说,传入 thenable 对象相当于给 new Promise() 传入了一个 匿名函数 ,只不过这个函数被放在了 thenable 对象的 then 字段上。这时候,resolve 方法会返回一个新的 promise ,就如同 new Promise() 一样,而这个 promise 的状态完全取决于 thenable 对象的 then 方法。如下:
// 通过 Promise 构造函数创建 let p_by_constructor = new Promise((resolve) => resolve('#1')); // 也可以将匿名函数作为对象的 then 字段,再将对象传入 Promise.resolve() let p_by_thenable = Promise.resolve({ then: (resolve) => resolve('#1') }); // 这两种方式都是等价的 // 打印实际值和期望值是否一样 let print = (expected, actual) => console.log(expected === actual); p_by_constructor.then(print.bind(null, '#1')); // true p_by_thenable.then(print.bind(null, '#1')); // true