# promise

忘了哪里转的,找到再补

  const isFunction = (obj) => typeof obj === 'function'
  const isObject = (obj) => !!(obj && typeof obj === 'object')
  const isThenable = (obj) =>
    (isFunction(obj) || isObject(obj)) && 'then' in obj
  const isPromise = (promise) => promise instanceof Promise

  const PENDING = 'pending'
  const FULFILLED = 'fulfilled'
  const REJECTED = 'rejected'

  function Promise(f) {
    this.result = null
    this.state = PENDING
    this.callbacks = []

    let onFulfilled = (value) => transition(this, FULFILLED, value)
    let onRejected = (reason) => transition(this, REJECTED, reason)

    let ignore = false
    let resolve = (value) => {
      if (ignore) return
      ignore = true
      resolvePromise(this, value, onFulfilled, onRejected)
    }
    let reject = (reason) => {
      if (ignore) return
      ignore = true
      onRejected(reason)
    }

    try {
      f(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }

  Promise.prototype.then = function (onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      let callback = { onFulfilled, onRejected, resolve, reject }

      if (this.state === PENDING) {
        this.callbacks.push(callback)
      } else {
        setTimeout(() => handleCallback(callback, this.state, this.result), 0)
      }
    })
  }

  const handleCallback = (callback, state, result) => {
    let { onFulfilled, onRejected, resolve, reject } = callback
    try {
      if (state === FULFILLED) {
        isFunction(onFulfilled)
          ? resolve(onFulfilled(result))
          : resolve(result)
      } else if (state === REJECTED) {
        isFunction(onRejected) ? resolve(onRejected(result)) : reject(result)
      }
    } catch (error) {
      reject(error)
    }
  }

  const handleCallbacks = (callbacks, state, result) => {
    while (callbacks.length) handleCallback(callbacks.shift(), state, result)
  }

  const transition = (promise, state, result) => {
    if (promise.state !== PENDING) return
    promise.state = state
    promise.result = result
    setTimeout(() => handleCallbacks(promise.callbacks, state, result), 0)
  }

  const resolvePromise = (promise, result, resolve, reject) => {
    if (result === promise) {
      let reason = new TypeError('Can not fufill promise with itself')
      return reject(reason)
    }

    if (isPromise(result)) {
      return result.then(resolve, reject)
    }

    if (isThenable(result)) {
      try {
        let then = result.then
        if (isFunction(then)) {
          return new Promise(then.bind(result)).then(resolve, reject)
        }
      } catch (error) {
        return reject(error)
      }
    }

    resolve(result)
  }

  const t = new Promise(resolve => {
    setTimeout(() => {
      resolve('aaaa')
    }, 2000);
  })

  t.then(res => {
    console.log(res, 'rrrrr')
  })
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
最后更新时间: 5/26/2021, 5:52:52 PM