Promise是什么

概念

抽象表述

  • Promise是一门新技术,是ES6的一种新规范

  • Promise是JS的进行异步编程的新的解决方案

    旧方案是单纯使用回调函数

    1
    2
    3
    4
    5
    6
    /**
    * 回调函数
    */
    require('fs').readFile('./index.html', (err, data) => {

    })

具体表述

  • 从语法上来说,Promise是一个构造函数
  • 从功能上来说:Promise封装了一个异步操作,并且可以获取成功或者失败的结果值

使用Promise的一些原因

  1. 指定回调函数方式更加灵活了
  2. 支持链式调用,可以解决回调地狱问题
    • 回调地狱会不便于阅读和不便于异常处理
    • 一般来说,我们采用Promise的链式调用来解决问题

初次使用

  • Promise方法内部有一个回调函数,函数参数为成功回调和失败回调,内部可以书写代码
  • then方法一般用于内部代码块执行完毕之后,再来执行的内容。如果需要上面代码块的内容,通常通过两个回调传值给then方法中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const p = new Promise((resolve, reject) => {
setTimeout(() => {
let n = Math.random() * 100
if (n <= 30) {
resolve(n) // 在此把n传给resolve回调
} else {
reject(n) // 否则在此把n传给reject回调
}
}, 1000)
})

p.then((value) => {
console.log(`success${value}`)
}, (reason) => {
console.log(`error${reason}`)
})

使用Promise封装一个ajax请求

原始的ajax请求,非axios,我们都是使用XMLHttpRequest来的

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
const axios = function (method, url, data) {
const p = new Promise((resolve, reject) => {
// 创建对象
const xhr = new XMLHttpRequest()
// 初始化
xhr.open(method, url)
// 发送
xhr.send(data)
// 处理响应结果
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
}
})
return p
}
const re = axios('GET', 'www.baidu.com', {dat: 100})
re.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})

utils.promisify风格

他会给你返回一个Promise版本,并为错误优先

你可以认为是将其拿了出来封装了Promise

1
2
3
4
5
6
7
8
9
10
11
const util = require('util')
const fs = require('fs')

let mineReadFile = util.promisify(fs.readFile)

const url = './src/content.txt'
mineReadFile(url).then(value => {
console.log(value)
}, reason => {
console.log(reason)
})

Promise的一些相关介绍

Promise的状态属性

指的是实例对象中的一个属性[PromiseState]

  • pending:未决定
  • resolved/fullfilled:成功
  • rejected:失败

Promise的状态改变指的就是pending转换为resolved或者rejected

Promise对象的值

指的是实例对象中的另一个属性[PromiseResult]

保存着异步任务成功或者失败的结果

  • resolve
  • reject

Promise的工作流程

  • Promise内部执行异步操作
  • 成功则执行resolved,失败则执行reject
  • 执行resolved或者reject后,返回的数据都会放在then方法中,then方法得到的结果是一个新的对象

Promise的相关API

  • Promise构造函数:Promise(executor)
    • 其中,executor为执行器:(resolve, reject) => {}
  • Promise.prototype.then:一般用于构造函数执行成功之后的操作:(onResolved, onRejected) => {}
    • onResolved为成功的回调
    • onRejected为失败的回调
  • Promise.prototype.catch:一般用于构造函数执行失败之后的操作:(onRejected) => {}
  • Promise.resolve(x):表示执行resolve直接传值给value

    • 如果内部传参x为非Promise,则直接为x

    • 如果内部传参x为Promise,则为x的resolve传递的参数

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      let p = Promise.resolve(
      new Promise((resolve, reject) => {
      resolve(123)
      })
      )

      p.then(value => {
      // output: 123, 而非Promise
      console.log(value)
      })
  • Promise.reject(x):表示执行reject直接传值给reason

    • 如果内部传参为x为Promise,则为x这个Promise本身

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      let p = Promise.reject(
      new Promise((resolve, reject) => {
      resolve(123)
      })
      )

      p.then(reason => {
      // output: Promise<rejected>, 而非内部数据
      console.log(reason)
      })
  • Promise.all(arr):表示一个Promise对象,其中arr是一个Promise数组,Promise.all的值为arr中所有的Promise的resolve构成的数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    let arr1 = Promise.resolve("arr1")
    let arr2 = new Promise((resolve, reject) => {
    resolve("arr2")
    })
    let arr3 = Promise.reject("arr3")
    let arr4 = Promise.reject("arr4")

    // 等到arr1和arr2都为resolve时,result的Promise对应的resolve值为["arr1", "arr2"]
    const result = Promise.all([arr1, arr2])
    const result2 = Promise.all([arr1, arr3, arr4])
    // 全部为resolve时返回数组
    console.log(result) // ["arr1", "arr2", "arr3"]
    // 如果有失败的回调,则返回的就是第一个失败的回调
    console.log(result2) // "arr3"
  • Promise.race(arr):表示一个Promise对象,其中arr是一个Promise数组Promise.race的值为arr中第一个为resolve的值

    • 注意:Promise的状态PromiseState为数组第一个Promise的状态
    • 如果有计时器,可以先计算他们的延时时间,先进行稳定的排序,再来判断是哪一个值和哪一个状态

    如下,无定时器:PromiseState的值为reject,但是PromiseResult的值为"arr1"

    1
    2
    3
    4
    5
    6
    let arr0 = Promise.reject("arr0")
    let arr1 = Promise.resolve("arr1")
    let arr2 = Promise.resolve("arr2")

    const result = Promise.race([arr0, arr1, arr2])
    console.log(result) // "arr1"

    如下,有定时器,我们可以将有延时的往后放,这样数组就是[arr1, arr2, arr0]

    最后我们得到的PromiseStatereject,而PromiseResultarr2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let arr0 = new Promise((resolve, reject) => {
    setTimeout(() => {
    reject("arr0")
    }, 1000)
    })
    let arr1 = Promise.reject("arr1")
    let arr2 = Promise.resolve("arr2")

    const result = Promise.race([arr0, arr1, arr2])
    console.log(result) // "arr1"

then方法

回调顺序问题

一般来说,都是先改变状态,再来执行then方法【注意,先执行then不代表先执行回调,回调还是得等到状态改变才会执行】,但是我们如果resolve或者reject在异步里面,就会先执行then方法

1
2
3
4
5
6
7
8
9
10
11
const result = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1")
console.log(3)
}, 1000)
})

result.then(value => {
console.log(value)
console.log(2)
})

我们可以看到Promise的状态为pending,证明是先执行后改变状态

在此我们得到了:

  • 如何先改变状态再回调?
    • 在执行器中直接调用resolve/reject
    • 延长更长时间才调用then
  • 什么时候拿到数据【指的就是回调函数什么时候执行 】
    • 先执行then,那么状态改变了之后【resolve执行完毕之后】,then内部的回调函数就会调用,得到数据
    • 先状态改变【resolve执行完毕之后】,那么执行then的时候,then内部的回调函数就会调用,得到数据

串联多任务

首先,我们根据then的特性,then返回的一定是一个Promise,所以then是可以链式调用的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("OK")
}, 1000)
})

p.then(value => {
return new Promise((resolve, reject) => {
resolve("success")
})
}).then(value => {
console.log(value) // output: success
}).then(value => {
console.log(value) // output: undefined
})

异常穿透

  • 当使用Promise的then链式调用的时候,可以在最后指定失败的回调
  • 前面任何操作出了异常,最后都会传到失败的回调来处理

我们可以理解成:在哪里出现失败了,都会返回同一个回调

我们采用catch来对then链条的每一个地方都进行集中失败回调:catch直接捕获第一个then的失败回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("OK")
}, 1000)
})

p.then(value => {
return new Promise((resolve, reject) => {
reject("success")
})
}).then(value => {
console.log(value)
}).then(value => {
console.log(value)
}).catch(reason => {
console.warn(reason) // output: success
})

中断Promise链

我们只有一种方式:返回一个Pending状态的Promise对象:

1
Promise(() => {})

因为一直在Pending,所以一直都没有then对象,需要等待信号传递来后,才会执行then,产生Promise对象,因此就在返回Promise(() => {}),Promise链就已经断裂:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("OK")
}, 1000)
})

p.then(value => {
return new Promise((resolve, reject) => {
reject("success")
})
}).then(value => {
return new Promise(() => {}) // 已经断裂
}).then(value => {
console.log(value)
}).catch(reason => {
console.warn(reason)
})

在上面,return new Promise(() => {})已经将Promise链断裂

自定义封装Promise

搭建基本功能,能够传值传信号给resolve或者reject

在这里有一点需要注意,就是this的指向问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Promise (executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const that = this
function resolve (data) {
// 修改对象的状态[PromiseState]
that.PromiseState = 'fullfilled'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data
}

function reject (data) {
that.PromiseState = 'error'
that.PromiseResult = data
}

executor(resolve, reject)
}
Promise.prototype.then = function (onResolved, onRejected) {

}

通过throw抛出异常

我们应该使用try-catch来进行抛出异常

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
function Promise (executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const that = this
function resolve (data) {
// 修改对象的状态[PromiseState]
that.PromiseState = 'fullfilled'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data
}

function reject (data) {
that.PromiseState = 'error'
that.PromiseResult = data
}

try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {

}

状态只能更改一次

那么我们需要从原来的基础上,加上一个状态判断,如果状态为pending时,我们才可以修改:

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
function Promise (executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const that = this
function resolve (data) {
// 状态为pending时,才可以修改
if (that.PromiseState === 'pending') {
// 修改对象的状态[PromiseState]
that.PromiseState = 'fullfilled'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data
}
}

function reject (data) {
if (that.PromiseState === 'pending') {
// 修改对象的状态[PromiseState]
that.PromiseState = 'error'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data
}
}

try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {

}

添加then方法,并返回一个Promise

我们需要搞清楚this的指向问题,在这里用了原型链,因此then的this指向是指向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
38
function Promise (executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const that = this
function resolve (data) {
// 状态为pending时,才可以修改
if (that.PromiseState === 'pending') {
// 修改对象的状态[PromiseState]
that.PromiseState = 'fullfilled'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data
}
}

function reject (data) {
if (that.PromiseState === 'pending') {
// 修改对象的状态[PromiseState]
that.PromiseState = 'error'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data
}
}

try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (this.PromiseState === 'fullfilled') {
onResolved(this.PromiseResult)
}

if (this.PromiseState === 'error') {
onRejected(this.PromiseResult)
}
}

异步任务回调,并可以指定多个回调

如果在我们创建的Promise里面,使用了异步函数,那么会导致我们that是拿不到数据的,因为我们没有对pending状态做判断

1
2
3
4
5
6
7
8
9
10
11
12
// 该Promise为自己封装的Promise
let p = new Promise((resolve, reject) => {
setTimeout(() => {
reject('no')
}, 1000)
})

p.then(value => {
console.log(value) //输出了undefined? why?
}, reason => {
console.log(reason)
})

因此,我们需要先将状态改变存储到一个容器中,然后依次执行

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
function Promise (executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []

const that = this
function resolve (data) {
// 状态为pending时,才可以修改
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'fullfilled'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onResolved(data)
})
}

function reject (data) {
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'error'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onRejected(data)
})
}

try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (this.PromiseState === 'fullfilled') {
onResolved(this.PromiseResult)
}

if (this.PromiseState === 'error') {
onRejected(this.PromiseResult)
}

if (this.PromiseState === 'pending') {
// 不会让pending的时候使状态丢失
this.callbacks.push({
onResolved,
onRejected
})
}
}

同步修改then状态

我们知道,then方法返回的也是一个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
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
function Promise (executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []

const that = this
function resolve (data) {
// 状态为pending时,才可以修改
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'fullfilled'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onResolved(data)
})
}

function reject (data) {
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'error'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onRejected(data)
})
}

try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
return new Promise((resolve, reject) => {
if (this.PromiseState === 'fullfilled') {
onResolved(this.PromiseResult)
}

if (this.PromiseState === 'error') {
onRejected(this.PromiseResult)
}

if (this.PromiseState === 'pending') {
// 不会让pending的时候使状态丢失
this.callbacks.push({
onResolved,
onRejected
})
}
})
}

let p = new Promise((resolve, reject) => {
setTimeout(() => {
reject('no')
}, 1000)
})

const res = p.then(value => {
console.log(value) //输出了undefined? why?
}, reason => {
console.log(reason)
})

console.log(res)

但是,我们得到的then是一直为pending状态:

我们需要也对then方法做同步:

同步的方法:

  • 在非等待状态下的then进行状态细分,如果返回值类型为Promise,则该then方法也可以直接调用then方法,因此需要一些分类操作
  • 如果返回值类型非Promise,则直接resolve即可
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
function Promise (executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []

const that = this
function resolve (data) {
// 状态为pending时,才可以修改
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'fullfilled'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onResolved(data)
})
}

function reject (data) {
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'error'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onRejected(data)
})
}

try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}

Promise.prototype.then = function (onResolved, onRejected) {
return new Promise((resolve, reject) => {
if (this.PromiseState === 'fullfilled') {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
// 如果该函数的返回值是Promise
result.then(v => {
// 需要resolve Promise内部的value
resolve(v)
}, r => {
reject(r)
})
} else {
// 如果返回值不是
resolve(this.PromiseResult)
}
}

if (this.PromiseState === 'error') {
onRejected(this.PromiseResult)
}

if (this.PromiseState === 'pending') {
// 不会让pending的时候使状态丢失
this.callbacks.push({
onResolved,
onRejected
})
}
})
}

let p = new Promise((resolve, reject) => {
//setTimeout(() => {
resolve('no')
//}, 1000)
})

const res = p.then(value => {
console.log(value) //输出了undefined? why?
return new Promise((resolve, reject) => {
resolve("???")
})
}, reason => {
console.log(reason)
})

console.log(res)

异步调用,修改then状态

在上面的Promise函数中,里面放回调,并没有达到我们的预期:

我们得要知道:在实例化对象之后,在then方法调用前,状态为pending,进入then状态时,没有进行我们上面所写的动作,因此我们需要在pending中进行改进:

比起上次,我们也对error错误也进行了异步处理,收集处理,throw处理等

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
function Promise (executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []

const that = this
function resolve (data) {
// 状态为pending时,才可以修改
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'fullfilled'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onResolved(data)
})
}

function reject (data) {
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'error'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onRejected(data)
})
}

try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}

Promise.prototype.then = function (onResolved, onRejected) {
const that = this
return new Promise((resolve, reject) => {
if (this.PromiseState === 'fullfilled') {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
// 如果该函数的返回值是Promise
result.then(v => {
// 需要resolve Promise内部的value
resolve(v)
}, r => {
reject(r)
})
} else {
// 如果返回值不是
resolve(this.PromiseResult)
}
}

if (this.PromiseState === 'error') {
try {
let result = onRejected(this.PromiseResult)
if (result instanceof Promise) {
// 如果该函数的返回值是Promise
result.then(v => {
// 需要resolve Promise内部的value
resolve(v)
}, r => {
reject(r)
})
} else {
// 如果返回值不是
reject(this.PromiseResult)
}
} catch (e) {
reject(e)
}
}

if (this.PromiseState === 'pending') {
// 不会让pending的时候使状态丢失
this.callbacks.push({
onResolved: function () {
let result = onResolved(that.PromiseResult)

if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(that.PromiseResult)
}
},
onRejected: function () {
// throw的错误收集
try {
let result = onRejected(that.PromiseResult)

if (result instanceof Promise) {
result.then(v => {
reject(v)
}, r => {
reject(r)
})
} else {
reject(that.PromiseResult)
}
} catch (e) {
reject(e)
}
}
})
}
})
}

let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('no')
}, 1000)
})

const res = p.then(value => {
console.log(value) //输出了undefined? why?
return new Promise((resolve, reject) => {
resolve("???")
})
}, reason => {
console.log(reason)
})

console.log(res)

效果图如下:

catch方法封装

我们添加catch方法:

1
2
3
4
Promise.prototype.catch = function (onRejected) {
// 相当于拒绝
return this.then(undefined, onRejected)
}

then方法需要执行检查,如果onReject返回值不是函数,就说明需要你重写一个函数

同理,onResolve也是如此

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
Promise.prototype.then = function (onResolved, onRejected) {
const that = this
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}

if (typeof onResolved !== function) {
onResolved = value => value
}

return new Promise((resolve, reject) => {
if (this.PromiseState === 'fullfilled') {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
// 如果该函数的返回值是Promise
result.then(v => {
// 需要resolve Promise内部的value
resolve(v)
}, r => {
reject(r)
})
} else {
// 如果返回值不是
resolve(this.PromiseResult)
}
}

if (this.PromiseState === 'error') {
try {
let result = onRejected(this.PromiseResult)
if (result instanceof Promise) {
// 如果该函数的返回值是Promise
result.then(v => {
// 需要resolve Promise内部的value
resolve(v)
}, r => {
reject(r)
})
} else {
// 如果返回值不是
reject(this.PromiseResult)
}
} catch (e) {
reject(e)
}
}

if (this.PromiseState === 'pending') {
// 不会让pending的时候使状态丢失
this.callbacks.push({
onResolved: function () {
let result = onResolved(that.PromiseResult)

if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(that.PromiseResult)
}
},
onRejected: function () {
// throw的错误收集
try {
let result = onRejected(that.PromiseResult)

if (result instanceof Promise) {
result.then(v => {
reject(v)
}, r => {
reject(r)
})
} else {
reject(that.PromiseResult)
}
} catch (e) {
reject(e)
}
}
})
}
})
}

添加resolve方法【支持Promise.resolve()】

我们只示范resolve,reject原理类似,不过多展示

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
function Promise (executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []

const that = this
function resolve (data) {
// 状态为pending时,才可以修改
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'fullfilled'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onResolved(data)
})
}

function reject (data) {
if (that.PromiseState !== 'pending') return
// 修改对象的状态[PromiseState]
that.PromiseState = 'error'
// 设置对象结果值[PromiseResult]
that.PromiseResult = data

that.callbacks.forEach((item) => {
item.onRejected(data)
})
}

try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}

Promise.prototype.then = function (onResolved, onRejected) {
const that = this
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}

if (typeof onResolved !== 'function') {
onResolved = value => value
}

return new Promise((resolve, reject) => {
if (this.PromiseState === 'fullfilled') {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
// 如果该函数的返回值是Promise
result.then(v => {
// 需要resolve Promise内部的value
resolve(v)
}, r => {
reject(r)
})
} else {
// 如果返回值不是
resolve(this.PromiseResult)
}
}

if (this.PromiseState === 'error') {
try {
let result = onRejected(this.PromiseResult)
if (result instanceof Promise) {
// 如果该函数的返回值是Promise
result.then(v => {
// 需要resolve Promise内部的value
resolve(v)
}, r => {
reject(r)
})
} else {
// 如果返回值不是
reject(this.PromiseResult)
}
} catch (e) {
reject(e)
}
}

if (this.PromiseState === 'pending') {
// 不会让pending的时候使状态丢失
this.callbacks.push({
onResolved: function () {
let result = onResolved(that.PromiseResult)

if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(that.PromiseResult)
}
},
onRejected: function () {
// throw的错误收集
try {
let result = onRejected(that.PromiseResult)

if (result instanceof Promise) {
result.then(v => {
reject(v)
}, r => {
reject(r)
})
} else {
reject(that.PromiseResult)
}
} catch (e) {
reject(e)
}
}
})
}
})
}

Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(value)
}
})
}

使then异步执行

原本的Promise中,then方法就是异步的,因此我们需要将then方法异步处理

我们只需要在原本的自定义then的基础上做异步函数包被

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
Promise.prototype.then = function (onResolved, onRejected) {
const that = this
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}

if (typeof onResolved !== 'function') {
onResolved = value => value
}

return new Promise((resolve, reject) => {
if (this.PromiseState === 'fullfilled') {
setTimeout(() => {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
// 如果该函数的返回值是Promise
result.then(v => {
// 需要resolve Promise内部的value
resolve(v)
}, r => {
reject(r)
})
} else {
// 如果返回值不是
resolve(this.PromiseResult)
}
})
}

if (this.PromiseState === 'error') {
setTimeout(() => {
try {
let result = onRejected(this.PromiseResult)
if (result instanceof Promise) {
// 如果该函数的返回值是Promise
result.then(v => {
// 需要resolve Promise内部的value
resolve(v)
}, r => {
reject(r)
})
} else {
// 如果返回值不是
reject(this.PromiseResult)
}
} catch (e) {
reject(e)
}
})
}

if (this.PromiseState === 'pending') {
setTimeout(() => {
// 不会让pending的时候使状态丢失
this.callbacks.push({
onResolved: function () {
let result = onResolved(that.PromiseResult)

if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(that.PromiseResult)
}
},
onRejected: function () {
// throw的错误收集
try {
let result = onRejected(that.PromiseResult)

if (result instanceof Promise) {
result.then(v => {
reject(v)
}, r => {
reject(r)
})
} else {
reject(that.PromiseResult)
}
} catch (e) {
reject(e)
}
}
})
})
}
})
}

结果如下:

我们明显看到,then输出的789是异步的