这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战
前面写了 Promise的入门和相关方法的使用, Promise的关键问题, 手写Promise核心原理(一), 手写Promise核心原理(二), 需要的童鞋请移步。这篇文章写下Promise相关方法的核心原理:
- 手写Promise.resolve(value)
- 手写Promise.reject(reason)
- 手写Promise.all(promises)
- 手写Promise.race(promises)
一、手写Promise.resolve(value)
Promise.resolve()是将现有对象转为 Promise 对象,所以需要在最外层返回一个新的Promise实例。 resolve方法接受的参数value分为两种,对应不同的操作如下:
- 当value为Promise实例或者value有then方法时,返回value.then的执行结果。因为当value为Promise实例时,若想得到其返回值,则需要调用其then方法;当value不为Promise实例但却有then方法时,立即执行then方法并返回结果。
- 其他时候返回该value。
Promise1.resolve = function(value) {
return new Promise1(function(resolve, reject) {
if (value instanceof Promise1 || value.then) {
value.then(resolve, reject);
} else {
resolve(value);
}
});
};
二、手写Promise.reject(reason)
Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。 所以代码很简单,返回一个Promise,其中直接将错误原因reject出去就行。
Promise1.reject = function(reason) {
return new Promise1(function(resolve, reject) {
reject(reason);
});
};
三、手写Promise.all(promises)
all方法的特点:
-
all方法接受一个具有Iterator接口的数据,其中若不为promise的元素将被转化为promise。
-
当所有promise实例的状态都变为fulfilled时,all方法返回一个包含所有Promise实例返回结果的数组;当有一个promise实例的状态都变为rejected时,all方法返回该pomise实例的返回结果。
all方法内部的操作:
- 返回一个新的Promise实例。
- 预先准备一个数组values,存储所有成功的promise的返回值。设置一个计数器resolveCount来计算成功promise的个数,可以用来判断是否所有promise都执行成功。
- 遍历参数promises,
-
若其中元素不为promsie实例则变为promise实例,前面讲了Promise.resolve()方法便是将现有对象转化为promised对象。
-
对每个元素执行then操作,当失败时则直接reject,当成功时将计数器加1并将返回值插入到values数组中,当所有promise都执行成功时,将成功的返回值组成的数组values resolve出去。
Promise1.all = function(promises) {
var _this = this;
return new Promise1(function(resolve, reject) {
var values = new Array(promises.length);
var resolveCount = 0;
promises.forEach(function(promiseItem, index) {
if (!(promiseItem instanceof Promise1)) {
promiseItem = _this.resolve(promiseItem);
}
promiseItem.then(
function(value) {
resolveCount++;
values[index] = value;
if (resolveCount == promises.length) {
resolve(values);
}
},
function(reason) {
reject(reason);
}
);
});
});
};
四、手写Promise.race(promises)
race方法的特点:
-
race方法接收的参数与all方法一样,都是接收一个具有Iterator接口的数据,其中若不为promise的元素将被转化为promise。
-
race方法的返回结果为先执行完的第一个promsie实例的返回结果。
race方法内部的操作:
- 返回一个新的Promise实例。
- 遍历参数promises,
- 若其中元素不为promsie实例则变为promise实例,前面讲了Promise.resolve()方法便是将现有对象转化为promised对象。
- 对每个元素执行then操作,并直接将结果resolve或reject出去。此时无论哪一个promise先执行完成,将结果返回出去了,后面的promise都无法再改变状态了。
Promise1.race = function(promises) {
var _this = this;
return new Promise(function(resolve, reject) {
promises.forEach(function(promiseItem) {
if (!(promiseItem instanceof Promise1)) {
promiseItem = _this.resolve(promiseItem);
}
promiseItem.then(
function(value) {
resolve(value);
},
function(reason) {
reject(reason);
}
);
});
});
};