Promise(三):拓展方法实现
上次把 Promise 简单的实现了基本功能,趁热打铁,我们来实现一下它里面的拓展方法。
# myPromise.prototype.catch
myPromise.prototype.catch = function (rejectFun) {
return this.then(null, rejectFun);
};
1
2
3
2
3
catch 方法实现起来还是简单的,通过调用 Promise 的 then 方法,只传入失败的回调;then 方法会把值传递下去。
# myPromise.prototype.finally
不管成功还是失败,都会执行
myPromise.prototype.finally = function (finallyFun) {
return this.then((res) => {
finallyFun();
return res;
}).catch((err) => {
fiinallyFun();
return err;
});
};
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# myPromise.resolve
返回一个成功的 Promise
myPromise.resolve = function (res) {
return new myPromise((resolve) => {
resolve(res);
});
};
1
2
3
4
5
2
3
4
5
# myPromise.reject
返回一个失败的 Promise
myPromise.reject = function (res) {
return new myPromise((resolve, reject) => {
reject(res);
});
};
1
2
3
4
5
2
3
4
5
# myPromise.all
- 返回一个 Promsie 实例,接收一个可迭代的对象,返回值是一个数组
- 等参数内的值都执行成功才返回成功,只要有一个值返回失败,则返回失败
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;
};
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
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
// 测试
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
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
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
其中一个失败时
总结: 1、Promise.all()接受一个 Array 类型的参数 2、只有数组中全部的 Promise 都变为 resolve 的时候 3、返回一个新的 Promise 实例 4、只要有一个失败,状态就变成 rejected
# myPromise.race
返回一个 Promsie,接收一个数组作为参数,一旦数组其中一项执行,就返回执行结果。
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;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# myPromise.any
只要其中一个 Promsie 成功,就返回成功的那个;如果没有一个成功,就返回失败,把失败的错误集中在一起。
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;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
上次更新: 2022/09/06, 10:30:04