Skip to content

Commit cb2c677

Browse files
author
andrew
committed
Add promise propagation setion2 and section3
1 parent 7147b7b commit cb2c677

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

lesson17/README.md

+125
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,11 @@ var outputPromise = getInputPromise().then(function(fulfiled){
129129
现在outputPromise就变成了受function(fulfiled)或者function(rejected)控制状态的promise了。怎么理解这句话呢?
130130

131131
* 当function(fulfiled)或者function(rejected)返回一个值,比如一个字符串,数组,对象等等,那么outputPromise的状态就会变成fulfiled。
132+
132133
在下面这个例子中,我们可以看到,当我们把inputPromise的状态通过defer.resovle()变成fulfiled时,控制台输出fulfiled.
134+
133135
当我们把inputPromise的状态通过defer.reject()变成rejected,控制台输出rejected
136+
134137
```js
135138
/**
136139
* 通过defer获得promise
@@ -176,6 +179,128 @@ var outputPromise = getInputPromise().then(function(fulfiled){
176179
```
177180
* 当function(fulfiled)或者function(rejected)抛出异常时,那么outputPromise的状态就会变成rejected
178181

182+
```JS
183+
var Q = require('q');
184+
var fs = require('fs');
185+
var defer = Q.defer();
186+
187+
/**
188+
* 通过defer获得promise
189+
* @private
190+
*/
191+
function getInputPromise() {
192+
return defer.promise;
193+
}
194+
195+
/**
196+
* 当inputPromise状态由未完成变成fulfil时,调用function(fulfiled)
197+
* 当inputPromise状态由未完成变成rejected时,调用function(rejected)
198+
* 将then返回的promise赋给outputPromise
199+
* function(fulfiled) 和 function(rejected) 通过抛出异常将outputPromise的状态由
200+
* 未完成改变为reject
201+
* @private
202+
*/
203+
var outputPromise = getInputPromise().then(function(fulfiled){
204+
throw new Error('fulfiled');
205+
},function(rejected){
206+
throw new Error('rejected');
207+
});
208+
209+
/**
210+
* 当outputPromise状态由未完成变成fulfil时,调用function(fulfiled),控制台打印'[Error:fulfiled]'。
211+
* 当outputPromise状态由未完成变成rejected, 调用function(rejected), 控制台打印'[Error:rejected]'。
212+
*/
213+
outputPromise.then(function(fulfiled){
214+
console.log(fulfiled);
215+
},function(rejected){
216+
console.log(rejected);
217+
});
218+
219+
/**
220+
* 将inputPromise的状态由未完成变成rejected
221+
*/
222+
defer.reject();
223+
224+
/**
225+
* 将inputPromise的状态由未完成变成fulfiled
226+
*/
227+
//defer.resolve();
228+
```
229+
230+
* 当function(fulfiled)或者function(rejected)返回一个promise时,outputPromise就会成为这个新的promise.
231+
232+
这样做有什么意义呢? 主要在于聚合结果(Q.all),管理延时,异常恢复等等
233+
234+
比如说我们想要读取一个文件的内容,然后把这些内容打印出来。可能会写出这样的代码:
235+
236+
```js
237+
//错误的写法
238+
var outputPromise = getInputPromise().then(function(fulfiled){
239+
fs.readFile('test.txt','utf8',function(err,data){
240+
return data;
241+
});
242+
},function(rejected){
243+
throw new Error('rejected');
244+
});
245+
```
246+
247+
然而由于异步IO的原因,这样写是不行的。需要下面的方式:
248+
249+
```js
250+
var Q = require('q');
251+
var fs = require('fs');
252+
var defer = Q.defer();
253+
254+
/**
255+
* 通过defer获得promise
256+
* @private
257+
*/
258+
function getInputPromise() {
259+
return defer.promise;
260+
}
261+
262+
/**
263+
* 当inputPromise状态由未完成变成fulfil时,调用function(fulfiled)
264+
* 当inputPromise状态由未完成变成rejected时,调用function(rejected)
265+
* 将then返回的promise赋给outputPromise
266+
* function(fulfiled)将新的promise赋给outputPromise
267+
* 未完成改变为reject
268+
* @private
269+
*/
270+
var outputPromise = getInputPromise().then(function(fulfiled){
271+
var myDefer = Q.defer();
272+
fs.readFile('test.txt','utf8',function(err,data){
273+
if(!err && data) {
274+
myDefer.resolve(data);
275+
}
276+
});
277+
return myDefer.promise;
278+
},function(rejected){
279+
throw new Error('rejected');
280+
});
281+
282+
/**
283+
* 当outputPromise状态由未完成变成fulfil时,调用function(fulfiled),控制台打印'[Error:fulfiled]'。
284+
* 当outputPromise状态由未完成变成rejected, 调用function(rejected), 控制台打印'[Error:rejected]'。
285+
*/
286+
outputPromise.then(function(fulfiled){
287+
console.log(fulfiled);
288+
},function(rejected){
289+
console.log(rejected);
290+
});
291+
292+
/**
293+
* 将inputPromise的状态由未完成变成rejected
294+
*/
295+
//defer.reject();
296+
297+
/**
298+
* 将inputPromise的状态由未完成变成fulfiled
299+
*/
300+
defer.resolve();
301+
```
302+
303+
179304
这次我们要介绍的是 async 的 `mapLimit(arr, limit, iterator, callback)` 接口。另外,还有个常用的控制并发连接数的接口是 `queue(worker, concurrency)`,大家可以去 https://github.com/caolan/async#queueworker-concurrency 看看说明。
180305

181306
这回我就不带大家爬网站了,我们来专注知识点:并发连接数控制。

0 commit comments

Comments
 (0)