hgq's docs
主页
ES6-阮一峰 (opens new window)
Vue文档 (opens new window)
Axios文档 (opens new window)
Vue Router (opens new window)
Vuex文档 (opens new window)
面试题-Vue (opens new window)
面试题-JS (opens new window)

guoguoqiqi

漫不经心的向往
主页
ES6-阮一峰 (opens new window)
Vue文档 (opens new window)
Axios文档 (opens new window)
Vue Router (opens new window)
Vuex文档 (opens new window)
面试题-Vue (opens new window)
面试题-JS (opens new window)
  • call的实现
  • apply的实现
  • bind的实现
  • new的实现
  • instanceof的实现
  • Object create()的实现
  • Object assign()的实现
  • Promise的实现
  • 实现防抖函数(debounce)
  • 实现节流函数(throttle)
  • 深拷贝(deepclone)
  • 数组扁平化的实现(flat)
  • 函数柯里化
  • EventEmitter 实现
  • 数组的随机排序
  • 通用的事件侦听器函数
  • 实现一个JSONP
  • 数组的map方法
  • 数组的forEach方法
  • 数组的find方法
  • 数组的findIndex方法
  • 数组的some方法
  • 数组的filter方法
  • 数组的every方法
  • 数组的includes方法
  • 数组的fill方法
  • 数组的join方法
  • 数组的flat方法
  • 用setTimeout实现setInterval
  • 用setInterval实现setTimeout
  • 实现一个较完善的深拷贝
  • 代码手写
guoguoqiqi
2022-03-04

Promise的实现

class Promise {
  constructor(params) {
    //初始化state为pending
    this.state = 'pending';
    //成功的值,返回一般都是undefined
    this.value = undefined;
    //失败的原因,返回一般都是undefined
    this.reason = undefined;
    //成功执行函数队列
    this.onResolvedCallbacks = [];
    //失败执行函数队列
    this.onRejectedCallbacks = [];

    //success
    let resolve = value => {
      if (this.state === 'pending') {
        //state change
        this.state = 'fulfilled';
        //储存成功的值
        this.value = value;
        //一旦成功,调用函数队列
        this.onResolvedCallbacks.forEach(fn => fn());
      }
    };

    //error
    let reject = reason => {
      if (this.state === 'pending') {
        //state change
        this.state = 'rejected';
        //储存成功的原因
        this.reason = reason;
        //一旦失败,调用函数队列
        this.onRejectedCallbacks.forEach(fn => fn());
      }
    };
    try {
      params(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }
  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
    onRejected = typeof onRejected === 'function' ? onRejected : err => {
      throw err
    };
    let promise2 = new Promise((resolve, reject) => {
      //当状态是fulfilled时执行onFulfilled函数
      if (this.state === 'fulfilled') {
        //异步实现
        setTimeout(() => {
          try {
            let x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0);
      };
      //当状态是rejected时执行onRejected函数
      if (this.state === 'rejected') {
        //异步实现
        setTimeout(() => {
          try {
            let x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0);
      };
      //当状态是pending时,往onFulfilledCacks、onRejectedCacks里加入函数
      if (this.state === 'pending') {
        this.onResolvedCallbacks.push(() => {
          //异步实现
          setTimeout(() => {
            try {
              let x = onFulfilled(this.value);
              resolvePromise(promise2, x, resolve, reject);
            } catch (e) {
              reject(e);
            }
          }, 0);
        });
        this.onRejectedCallbacks.push(() => {
          //异步实现
          setTimeout(() => {
            try {
              let x = onRejected(this.reason);
              resolvePromise(promise2, x, resolve, reject);
            } catch (e) {
              reject(e);
            }
          }, 0)
        });
      };
    });
    return promise2;
  }
  catch(fn) {
    return this.then(null, fn);
  }
}

function resolvePromise(promise2, x, resolve, reject) {
  //循环引用报错
  if (x === promise2) {
    return reject(new TypeError('Chaining cycle detected for promise'));
  }
  //防止多次调用
  let called;
  //判断x
  if (x != null && (typeof x === 'object' || typeof x === 'function')) {
    try {
      let then = x.then;
      if (typeof then === 'function') {
        then.call(x, y => {
          if (called) return;
          called = true;
          resolvePromise(promise2, y, resolve, reject);
        }, err => {
          if (called) return;
          called = true;
          reject(err);
        })
      } else {
        resolve(x);
      }
    } catch (e) {
      if (called) return;
      called = true;
      reject(e);
    }
  } else {
    resolve(x);
  }
}
//resolve方法
Promise.resolve = function (val) {
  return new Promise((resolve, reject) => {
    resolve(val)
  });
}
//reject方法
Promise.reject = function (val) {
  return new Promise((resolve, reject) => {
    reject(val);
  });
}

const test = new Promise((res, rej) => {
  setTimeout(() => {
    res('resolve after 2000ms');
  }, 2000)
})

test.then(res => {
  console.error('res: ', res);	// res: resolve after 2000ms
})
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

← Object assign()的实现 实现防抖函数(debounce)→

最近更新
01
vuex数据持久化怎么做
05-22
02
vue的动态路由怎么配置使用
05-22
03
vue权限控制一般怎么做
05-22
更多文章>
Theme by Vdoing | Copyright © 2022-2022 Guoquoqiqi | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式