|
2 | 2 |
|
3 | 3 | * 含义 |
4 | 4 |
|
5 | | -Promies 对象是异步编程的解决方案之一,比传统的异步解决方案——回调函数更合理更强大。 |
| 5 | + Promies 对象是异步编程的解决方案之一,比传统的异步解决方案——回调函数更合理更强大。 |
6 | 6 |
|
7 | | -想象下这样的一个场景,在管理系统的新闻模块下,编辑新闻的时候,在获取到编辑详情之前,可能需要先获取到新闻的分类列表,新闻图片的类型列表,新闻发布者的列表之后,这样才能把对应的详情内容填充上去,因为这些选项都是 select 下拉菜单。那么这些内容都是通 AJAX 去异步请求的,为了保证所有的内容填充上去之前获取到所有的列表,回调函数的解决方案应该是这样的: |
| 7 | + 想象下这样的一个场景,在管理系统的新闻模块下,编辑新闻的时候,在获取到编辑详情之前,可能需要先获取到新闻的分类列表,新闻图片的类型列表,新闻发布者的列表之后,这样才能把对应的详情内容填充上去,因为这些选项都是 select 下拉菜单。那么这些内容都是通 AJAX 去异步请求的,为了保证所有的内容填充上去之前获取到所有的列表,回调函数的解决方案应该是这样的: |
8 | 8 |
|
9 | | -```javascript |
10 | | -//新闻的分类列表 |
11 | | -function getNewsType() { |
12 | | - $.ajax({ |
13 | | - ... |
14 | | - success: function(res) { |
| 9 | + ```javascript |
| 10 | + //新闻的分类列表 |
| 11 | + function getNewsType() { |
| 12 | + $.ajax({ |
15 | 13 | ... |
16 | | - }, |
17 | | - complete: function() { |
18 | | - getImgType(); |
19 | | - } |
20 | | - }) |
21 | | -} |
22 | | -//获取新闻图片的类型列表 |
23 | | -function getImgType() { |
24 | | - $.ajax({ |
25 | | - ... |
26 | | - success: function(res) { |
| 14 | + success: function(res) { |
| 15 | + ... |
| 16 | + }, |
| 17 | + complete: function() { |
| 18 | + getImgType(); |
| 19 | + } |
| 20 | + }) |
| 21 | + } |
| 22 | + //获取新闻图片的类型列表 |
| 23 | + function getImgType() { |
| 24 | + $.ajax({ |
27 | 25 | ... |
28 | | - }, |
29 | | - complete: function() { |
30 | | - getAuthor(); |
31 | | - } |
32 | | - }) |
33 | | -} |
34 | | -//获取新闻发布者的列表 |
35 | | -function getAuthor() { |
36 | | - $.ajax({ |
37 | | - ... |
38 | | - success: function(res) { |
| 26 | + success: function(res) { |
| 27 | + ... |
| 28 | + }, |
| 29 | + complete: function() { |
| 30 | + getAuthor(); |
| 31 | + } |
| 32 | + }) |
| 33 | + } |
| 34 | + //获取新闻发布者的列表 |
| 35 | + function getAuthor() { |
| 36 | + $.ajax({ |
39 | 37 | ... |
40 | | - }, |
41 | | - complete: function() { |
42 | | - getNewsDetail(); |
43 | | - } |
44 | | - }) |
45 | | -} |
46 | | -//获取编辑新闻详情 |
47 | | -function getNewsDetail() { |
48 | | - $.ajax({ |
49 | | - ... |
50 | | - success: function(res) { |
| 38 | + success: function(res) { |
| 39 | + ... |
| 40 | + }, |
| 41 | + complete: function() { |
| 42 | + getNewsDetail(); |
| 43 | + } |
| 44 | + }) |
| 45 | + } |
| 46 | + //获取编辑新闻详情 |
| 47 | + function getNewsDetail() { |
| 48 | + $.ajax({ |
51 | 49 | ... |
52 | | - } |
53 | | - }) |
54 | | -} |
| 50 | + success: function(res) { |
| 51 | + ... |
| 52 | + } |
| 53 | + }) |
| 54 | + } |
55 | 55 |
|
56 | | -``` |
| 56 | + ``` |
57 | 57 |
|
58 | | -可以看到,这种解决方案是一层嵌套一层的,当嵌套的层数多了,代码就会变得难以维护了。Promise 的出现就是为了解决异步回调函数的回调地狱问题。 |
| 58 | + 可以看到,这种解决方案是一层嵌套一层的,当嵌套的层数多了,代码就会变得难以维护了。Promise 的出现就是为了解决异步回调函数的回调地狱问题。 |
59 | 59 |
|
60 | | -Promise 其实就相当于一个容器,里面存放着在未来才会结束的异步操作结果。Promise 有三种状态:pending(进行中),fulfilled(已成功) 和 rejected(已失败)。只有异步操作的结果才能改变当前的状态,并且当状态一旦发现改变后就固定了状态,后面的操作将不会引发状态的改变。 |
| 60 | + Promise 其实就相当于一个容器,里面存放着在未来才会结束的异步操作结果。Promise 有三种状态:pending(进行中),fulfilled(已成功) 和 rejected(已失败)。只有异步操作的结果才能改变当前的状态,并且当状态一旦发现改变后就固定了状态,后面的操作将不会引发状态的改变。 |
61 | 61 |
|
62 | | -* 基本使用 |
| 62 | + * 基本使用 |
63 | 63 |
|
64 | | -Promise 对象是一个构造函数,使用起来很简单,用 new 关键字去实例化就行了。 |
65 | | -```javascript |
66 | | -const promise = new Promise(function(resolve, reject) { |
67 | | - if(...) { |
68 | | - //异步操作成功 |
69 | | - resolve(); |
70 | | - }else { |
71 | | - //异步操作失败 |
72 | | - reject(); |
73 | | - } |
74 | | -}); |
75 | | -``` |
| 64 | + Promise 对象是一个构造函数,使用起来很简单,用 new 关键字去实例化就行了。 |
| 65 | + ```javascript |
| 66 | + const promise = new Promise(function(resolve, reject) { |
| 67 | + if(...) { |
| 68 | + //异步操作成功 |
| 69 | + resolve(); |
| 70 | + }else { |
| 71 | + //异步操作失败 |
| 72 | + reject(); |
| 73 | + } |
| 74 | + }); |
| 75 | + ``` |
76 | 76 |
|
77 | | -Promise 构造函数接收一个函数作为参数,这个函数中存在两个参数 resolve 和 reject。这两个参数都是函数,它们的作用分别是,resolve 表示异步操作成功后将 Promise 状态从 pending 改变为 fulfilled,如果带有参数的话会将参数传递出去;reject 表示异步操作失败后将 Promise 状态从 pending 改变为 rejected,如果带有参数的话会将参数传递出去。 |
| 77 | + Promise 构造函数接收一个函数作为参数,这个函数中存在两个参数 resolve 和 reject。这两个参数都是函数,它们的作用分别是,resolve 表示异步操作成功后将 Promise 状态从 pending 改变为 fulfilled,如果带有参数的话会将参数传递出去;reject 表示异步操作失败后将 Promise 状态从 pending 改变为 rejected,如果带有参数的话会将参数传递出去。 |
78 | 78 |
|
79 | 79 | * Promise.prototype.then |
80 | 80 |
|
81 | | -Promise 状态发生改变后可以捕捉到状态的改变并且使用 then 方法指定状态改变后的回调函数。 |
| 81 | + Promise 状态发生改变后可以捕捉到状态的改变并且使用 then 方法指定状态改变后的回调函数。 |
82 | 82 |
|
83 | | -```javascript |
84 | | -const promise = new Promise(function(resolve, reject) { |
85 | | - if(...) { |
86 | | - //异步操作成功 |
87 | | - resolve(); |
88 | | - }else { |
89 | | - //异步操作失败 |
90 | | - reject(); |
91 | | - } |
92 | | -}); |
| 83 | + ```javascript |
| 84 | + const promise = new Promise(function(resolve, reject) { |
| 85 | + if(...) { |
| 86 | + //异步操作成功 |
| 87 | + resolve(); |
| 88 | + }else { |
| 89 | + //异步操作失败 |
| 90 | + reject(); |
| 91 | + } |
| 92 | + }); |
93 | 93 |
|
94 | | -promise.then(function() { |
95 | | - //状态变为 fulfilled 的回调函数 |
96 | | -}, function() { |
97 | | - //状态变为 rejected 的回调函数 |
98 | | -}) |
99 | | -``` |
100 | | -then 方法接收两个函数作为参数,第一个参数是状态变为 fulfilled 的回调函数,第二个参数是状态变为 rejected 的回调函数,两个函数分别接收异步操作结果传递出来的参数作为函数的参数。 |
| 94 | + promise.then(function() { |
| 95 | + //状态变为 fulfilled 的回调函数 |
| 96 | + }, function() { |
| 97 | + //状态变为 rejected 的回调函数 |
| 98 | + }) |
| 99 | + ``` |
| 100 | + then 方法接收两个函数作为参数,第一个参数是状态变为 fulfilled 的回调函数,第二个参数是状态变为 rejected 的回调函数,两个函数分别接收异步操作结果传递出来的参数作为函数的参数。 |
101 | 101 |
|
102 | 102 | * Promise.prototype.catch |
103 | 103 |
|
104 | | -状态变为 rejected 的回调函数其实可以使用 catch 方法代替的,并且也推荐使用这种方式,就是这样: |
| 104 | + 状态变为 rejected 的回调函数其实可以使用 catch 方法代替的,并且也推荐使用这种方式,就是这样: |
105 | 105 |
|
106 | | -```javascript |
107 | | -function test(state) { |
108 | | - return new Promise(function(resolve, reject) { |
109 | | - if(state) { |
110 | | - resolve('success'); |
111 | | - }else { |
112 | | - resolve('fail'); |
113 | | - } |
| 106 | + ```javascript |
| 107 | + function test(state) { |
| 108 | + return new Promise(function(resolve, reject) { |
| 109 | + if(state) { |
| 110 | + resolve('success'); |
| 111 | + }else { |
| 112 | + resolve('fail'); |
| 113 | + } |
| 114 | + }) |
| 115 | + } |
| 116 | +
|
| 117 | + //写法一 |
| 118 | + test(false).then(function(state) { |
| 119 | + console.log('状态:' + state); |
| 120 | + }, function(state) { |
| 121 | + console.log('状态:' + state); |
114 | 122 | }) |
115 | | -} |
116 | | - |
117 | | -//写法一 |
118 | | -test(false).then(function(state) { |
119 | | - console.log('状态:' + state); |
120 | | -}, function(state) { |
121 | | - console.log('状态:' + state); |
122 | | -}) |
123 | | -//写法二 |
124 | | -test(false).then(function(state) { |
125 | | - console.log('状态:' + state); |
126 | | -}).catch(function(state) { |
127 | | - console.log('状态:' + state); |
128 | | -}) |
129 | | -``` |
130 | | - |
131 | | -catch 方法可以捕获到 Promise 异步操作失败或者内部抛出错误,甚至可以捕获到前面的 then 方法的回调函数抛出的错误,这也是用 catch 代替状态变为 rejected 的回调函数的原因,catch 方法的定位就是用来捕获错误信息的。 |
| 123 | + //写法二 |
| 124 | + test(false).then(function(state) { |
| 125 | + console.log('状态:' + state); |
| 126 | + }).catch(function(state) { |
| 127 | + console.log('状态:' + state); |
| 128 | + }) |
| 129 | + ``` |
| 130 | + |
| 131 | + catch 方法可以捕获到 Promise 异步操作失败或者内部抛出错误,甚至可以捕获到前面的 then 方法的回调函数抛出的错误,这也是用 catch 代替状态变为 rejected 的回调函数的原因,catch 方法的定位就是用来捕获错误信息的。 |
132 | 132 |
|
133 | 133 | * Promise.prototype.finally |
134 | 134 |
|
135 | | -finally 方法表示的是不管 Promise 状态变成哪种状态,finally 方法总是会执行的,类似于 $.ajax 中的 complete 方法。 |
| 135 | + finally 方法表示的是不管 Promise 状态变成哪种状态,finally 方法总是会执行的,类似于 $.ajax 中的 complete 方法。 |
136 | 136 |
|
137 | 137 | * Promise.all |
138 | 138 |
|
139 | | -Promise.all 接收多个 Promise 实例的数组作为参数,将这些实例包装成一个新的 Promise 实例。新的 Promise 实例的状态由数组中的 Promise 实例决定。使用 all 方法可以并行执行多个异步操作。 |
140 | | -回到前面假设的那个场景,使用 Promise.all 方法处理应该是这样的: |
141 | | -```javascript |
142 | | -//新闻的分类列表 |
143 | | -function getNewsType() { |
144 | | - return new Promise(function(resolve, reject) { |
145 | | - $.ajax({ |
146 | | - ... |
147 | | - success: function(res) { |
148 | | - resolve(); |
149 | | - } |
| 139 | + Promise.all 接收多个 Promise 实例的数组作为参数,将这些实例包装成一个新的 Promise 实例。新的 Promise 实例的状态由数组中的 Promise 实例决定。使用 all 方法可以并行执行多个异步操作。 |
| 140 | + 回到前面假设的那个场景,使用 Promise.all 方法处理应该是这样的: |
| 141 | + ```javascript |
| 142 | + //新闻的分类列表 |
| 143 | + function getNewsType() { |
| 144 | + return new Promise(function(resolve, reject) { |
| 145 | + $.ajax({ |
| 146 | + ... |
| 147 | + success: function(res) { |
| 148 | + resolve(); |
| 149 | + } |
| 150 | + }) |
150 | 151 | }) |
151 | | - }) |
152 | | -} |
153 | | -//获取新闻图片的类型列表 |
154 | | -function getImgType() { |
155 | | - return new Promise(function(resolve, reject) { |
156 | | - $.ajax({ |
157 | | - ... |
158 | | - success: function(res) { |
159 | | - resolve(); |
160 | | - } |
| 152 | + } |
| 153 | + //获取新闻图片的类型列表 |
| 154 | + function getImgType() { |
| 155 | + return new Promise(function(resolve, reject) { |
| 156 | + $.ajax({ |
| 157 | + ... |
| 158 | + success: function(res) { |
| 159 | + resolve(); |
| 160 | + } |
| 161 | + }) |
161 | 162 | }) |
162 | | - }) |
163 | | -} |
164 | | -//获取新闻发布者的列表 |
165 | | -function getAuthor() { |
166 | | - return new Promise(function(resolve, reject) { |
| 163 | + } |
| 164 | + //获取新闻发布者的列表 |
| 165 | + function getAuthor() { |
| 166 | + return new Promise(function(resolve, reject) { |
| 167 | + $.ajax({ |
| 168 | + ... |
| 169 | + success: function(res) { |
| 170 | + resolve(); |
| 171 | + } |
| 172 | + }) |
| 173 | + }) |
| 174 | + } |
| 175 | + //获取编辑新闻详情 |
| 176 | + function getNewsDetail() { |
167 | 177 | $.ajax({ |
168 | 178 | ... |
169 | 179 | success: function(res) { |
170 | | - resolve(); |
| 180 | + ... |
171 | 181 | } |
172 | 182 | }) |
173 | | - }) |
174 | | -} |
175 | | -//获取编辑新闻详情 |
176 | | -function getNewsDetail() { |
177 | | - $.ajax({ |
178 | | - ... |
179 | | - success: function(res) { |
180 | | - ... |
181 | | - } |
182 | | - }) |
183 | | -} |
| 183 | + } |
184 | 184 |
|
185 | | -Promise.all([getNewsType(), getImgType(), getAuthor()]).then(function() { |
186 | | - //只有当所有的 Promise 对象的状态都变为 fulfilled,Promise.all 生成的 Promise 实例的状态是 fulfilled |
187 | | - getNewsDetail(); |
188 | | -}).catch(function() { |
189 | | - //当只要有一个Promise 对象的状态都变为 rejected,Promise.all 生成的 Promise 实例的状态是 rejected |
190 | | -}) |
191 | | -``` |
| 185 | + Promise.all([getNewsType(), getImgType(), getAuthor()]).then(function() { |
| 186 | + //只有当所有的 Promise 对象的状态都变为 fulfilled,Promise.all 生成的 Promise 实例的状态是 fulfilled |
| 187 | + getNewsDetail(); |
| 188 | + }).catch(function() { |
| 189 | + //当只要有一个Promise 对象的状态都变为 rejected,Promise.all 生成的 Promise 实例的状态是 rejected |
| 190 | + }) |
| 191 | + ``` |
192 | 192 |
|
193 | 193 | * Promise.race |
194 | 194 |
|
195 | | -Promise.race 和 Promise.all 的区别就是,只要参数数组中的 Promise 实例的状态有一个率先改变,那么 Promise.race 生成的 Promise 实例的状态就是率先改变的 Promise 实例状态。 |
| 195 | + Promise.race 和 Promise.all 的区别就是,只要参数数组中的 Promise 实例的状态有一个率先改变,那么 Promise.race 生成的 Promise 实例的状态就是率先改变的 Promise 实例状态。 |
196 | 196 |
|
197 | 197 | * Promise.resolve |
198 | | -将接收的参数转为 Promise 对象。 |
| 198 | + |
| 199 | + 将接收的参数转为 Promise 对象。 |
199 | 200 |
|
200 | 201 | * Promise.reject |
201 | | -Promise.reject 首先会生存一个 Promise 实例对象,再将 Promise 实例状态转为 rejected。 |
| 202 | + |
| 203 | + Promise.reject 首先会生存一个 Promise 实例对象,再将 Promise 实例状态转为 rejected。 |
0 commit comments