Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)
如果调用resolve函数和reject函数时带有参数,那么它们的参数会被传递给回调函数。reject函数的参数通常是Error对象的实例,表示抛出的错误;resolve函数的参数除了正常的值以外,还可能是另一个Promise实例,表示异步操作的结果有可能是一个值,也有可能是另一个异步操作
1 2 3 4 5 6 7 8 9 10 11 12
| var p1 = new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('fail')), 3000) }) var p2 = new Promise(function (resolve, reject) { setTimeout(() => resolve(p1), 1000) }) p2 .then(result => console.log(result)) .catch(error => console.log(error))
|
Promise.prototype.then()Promise.prototype.catch()
Promise实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为Promise实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
1 2 3 4 5 6
| p.then((val) => console.log("fulfilled:", val)) .catch((err) => console.log("rejected:", err)); p.then((val) => console.log("fulfilled:", val)) .then(null, (err) => console.log("rejected:", err));
|
Promise.all()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Promise.prototype.all = function(promises) { let results = [] return new Promise((resolve, rejected) => { for(let i=0; i<promises.length; i++) { promises[i].then((res) => { results.push(res) if (i === promises.length -1) { resolve(results) } }).catch((err) => { reject(err) }) } }) }
|
Promise.race()
Promise.resolve()
有时需要将现有对象转为Promise对象,Promise.resolve方法就起到这个作用。
1 2 3
| Promise.resolve(42).then(function(value){ console.log(value); });
|
Promise.reject()
Promise.reject(reason)方法也会返回一个新的Promise实例,该实例的状态为rejected。它的参数用法与Promise.resolve方法完全一致。
手写Promise的polyfill
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| const PENDING = 'pending' const FULFILLED = 'fulfilled' const REJECTED = 'rejected' function MyPromise(executor) { this.state = PENDING; this.value = null; this.reason = null; this.onFulfilledCallbacks = []; this.onRejectedCallbacks = []; var self = this; function resolve(val) { if (self.state === PENDING) { self.state = FULFILLED; self.value = value; self.onFulfilledCallbacks.forEach(function(fulfilledCallback) { fulfilledCallback(); }); } } function rejected(reason) { if (self.state === PENDING) { self.state = REJECTED; self.reason = reason; self.onRejectedCallbacks.forEach(function(rejectedCallback) { rejectedCallback(); }); } } try { executor(resolve, rejected); } catch (reason) { reject(reason); } } MyPromise.prototype.then = function(onResolve, onRejected) { if (self.state === PENDING) { self.onFulfilledCallbacks.push(() => { onFuifilled(self.value); }); self.onRejectedCallbacks.push(() => { onRejected(self.reason); }); } if (this.state === FULFILLED) { onResolve(this.value) } if (this.state === REJECTED) { onRejected(this.reason) } }
|