上次把 Promise 简单的实现了基本功能,趁热打铁,我们来实现一下它里面的拓展方法。

myPromise.prototype.catch

1
2
3
myPromise.prototype.catch = function (rejectFun) {
return this.then(null, rejectFun);
};

catch 方法实现起来还是简单的,通过调用 Promise 的 then 方法,只传入失败的回调;then 方法会把值传递下去。


myPromise.prototype.finally

不管成功还是失败,都会执行

1
2
3
4
5
6
7
8
9
myPromise.prototype.finally = function (finallyFun) {
return this.then((res) => {
finallyFun();
return res;
}).catch((err) => {
fiinallyFun();
return err;
});
};

myPromise.resolve

返回一个成功的 Promise

1
2
3
4
5
myPromise.resolve = function (res) {
return new myPromise((resolve) => {
resolve(res);
});
};

myPromise.reject

返回一个失败的 Promise

1
2
3
4
5
myPromise.reject = function (res) {
return new myPromise((resolve, reject) => {
reject(res);
});
};

myPromise.all

  • 返回一个 Promsie 实例,接收一个可迭代的对象,返回值是一个数组
  • 等参数内的值都执行成功才返回成功,只要有一个值返回失败,则返回失败
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
myPromise.all = function (arr) {
/*判断参数类型*/
if (!Array.isArray(arr)) {
return new TypeError("参数类型错误,必须是数组");
}
let resolve;
let reject;
const promise = new myPromise((r, j) => {
resolve = r;
reject = j;
});

let fufilledCount = 0;
let index = 0;
const result = [];
/*记录当前遍历的index*/
const wrapFufilled = (i) => {
return (val) => {
fufilledCount += 1;
result[i] = val;
if (fufilledCount >= index) {
resolve(result);
}
};
};
const wrapRejected = (i) => {
return (err) => {
reject(err);
};
};

for (let item of arr) {
myPromise.resolve(item).then(wrapFufilled(index), wrapRejected(index));
index += 1;
}
return promise;
};

调用一下 myPromise.all

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
// 测试
const pro1 = new myPromise((res, rej) => {
setTimeout(() => {
res("1");
}, 1000);
});
const pro2 = new myPromise((res, rej) => {
setTimeout(() => {
// res('2')
rej("错误");
}, 2000);
});
const pro3 = new myPromise((res, rej) => {
setTimeout(() => {
res("3");
}, 3000);
});

const proAll = myPromise
.all([pro1, pro2, pro3])
.then(
(res) => console.log(res) // 3秒之后打印 ["1", "2", "3"]
)
.catch((e) => {
console.log(e); // “错误”
});

其中一个失败时

总结:
1、Promise.all()接受一个 Array 类型的参数
2、只有数组中全部的 Promise 都变为 resolve 的时候
3、返回一个新的 Promise 实例
4、只要有一个失败,状态就变成 rejected


myPromise.race

返回一个 Promsie,接收一个数组作为参数,一旦数组其中一项执行,就返回执行结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
myPromise.race = function (arr) {
let resolve;
let reject;
const promise = new myPromsie((r, j) => {
resolve = r;
reject = j;
});

for (let item of arr) {
myPromise.resolve(item).then(
(val) => resolve(val),
(err) => reject(err)
);
}
return promise;
};

myPromise.any

只要其中一个 Promsie 成功,就返回成功的那个;如果没有一个成功,就返回失败,把失败的错误集中在一起。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
myPromise.any = function (arr) {
let resolve;
let reject;
const promise = new myPromise((r, j) => {
resolve = r;
reject = j;
});

let errCount = 0;
let arrCount = 0;
for (let item of arr) {
arrCount += 1;
myPromise.resolve(item).then(
(val) => resolve(val),
(err) => {
errCount += 1;
if (errCount >= arrCount) {
reject(new AggregateError("所有Promsie都失败"));
}
}
);
}
return promise;
};