IMAGINE'S BLOG IMAGINE'S BLOG
首页
  • 原生JS

    • JavaScript
  • 前端框架扩展

    • Vue
    • React
    • UI组件库
  • HTML
  • CSS
  • 浏览器
  • 分类
  • 标签
  • 归档
  • 技术文档
  • GitHub相关
  • Nodejs
关于
  • 网站
  • 友情链接
GitHub (opens new window)

peng

平平无奇的web前端开发一枚
首页
  • 原生JS

    • JavaScript
  • 前端框架扩展

    • Vue
    • React
    • UI组件库
  • HTML
  • CSS
  • 浏览器
  • 分类
  • 标签
  • 归档
  • 技术文档
  • GitHub相关
  • Nodejs
关于
  • 网站
  • 友情链接
GitHub (opens new window)
  • JavaScript

    • javascript 之 this 指向问题
    • JS循环遍历方法
    • 前端常用公共方法工具类
    • JS声明提升
    • JS合并数组对象中key值相同的数据
    • 数组对象求和
    • 前端路由实现
    • Promise(一):Promise 认识
    • Promise(二):手动实现一个 Promise
    • Promise(三):拓展方法实现
      • myPromise.prototype.catch
      • myPromise.prototype.finally
      • myPromise.resolve
      • myPromise.reject
      • myPromise.all
      • myPromise.race
      • myPromise.any
    • JS forEach踩坑
    • ES6-ES12 特性
    • async/await
    • JavaScript 数组去重
    • js对象排序
    • js if/else 语句优化策略
    • js深拷贝
    • 正则表达式校验
    • js笛卡尔积
    • Axios 封装
  • 框架扩展

  • 前端乱炖
  • JavaScript
peng
2022-09-05
目录

Promise(三):拓展方法实现

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

# myPromise.prototype.catch

myPromise.prototype.catch = function (rejectFun) {
  return this.then(null, rejectFun);
};
1
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

# myPromise.resolve

返回一个成功的 Promise

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

# myPromise.reject

返回一个失败的 Promise

myPromise.reject = function (res) {
  return new myPromise((resolve, reject) => {
    reject(res);
  });
};
1
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

调用一下 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

其中一个失败时

总结: 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

# 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
#JavaScript
上次更新: 2022/09/06, 10:30:04
Promise(二):手动实现一个 Promise
JS forEach踩坑

← Promise(二):手动实现一个 Promise JS forEach踩坑→

最近更新
01
Axios 封装
09-06
02
MySQL数据库常用操作
09-06
03
解决element表格数据量过大导致页面渲染缓慢、卡顿问题
09-06
更多文章>
Theme by Vdoing | Copyright © 2020-2024 peng | IMAGINE
image | imgloc.com
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式