Skip to content

Commit d21f10c

Browse files
committed
add more content
Signed-off-by: meathill <meathill@gmail.com>
1 parent cd0584f commit d21f10c

File tree

6 files changed

+129
-5
lines changed

6 files changed

+129
-5
lines changed

Diff for: 02-3-node-js.md

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
Node.js 8 的新方法
2+
========
3+
4+
Node.js 8 于5月底正式发布,带来了[很多新特性](https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V8.md#8.0.0)。其中,`util.promisify()`,尤其值得我们注意。
5+
6+
## `util.promisify()`
7+
8+
虽然 Promise 已经普及,但是 Node.js 里仍然有大量依赖回调的异步函数,如果我们把每个函数都封装一遍,那真是齁麻烦齁麻烦的,比齁还麻烦。
9+
10+
所以 Node.js 8 就提供了 `util.promisify()` ——“Promise 化”——这个方法,方便我们把原来的异步回调方法改成支持 Promise 的方法。接下来,想继续 `.then().then().then()` 搞队列,还是 Await 就看实际需要了。
11+
12+
我们看下官方范例,让读取目录文件状态的 `fs.stat` 支持 Promise:
13+
14+
```javascript
15+
const util = require('util');
16+
const fs = require('fs');
17+
18+
const stat = util.promisify(fs.stat);
19+
stat('.')
20+
.then((stats) => {
21+
// Do something with `stats`
22+
})
23+
.catch((error) => {
24+
// Handle the error.
25+
});
26+
```
27+
28+
怎么样,很简单吧?按照文档的说法,只要符合 Node.js 的回调风格,所有函数都可以这样转换。也就是说,只要满足下面两个条件,无论是不是原生方法,都可以:
29+
30+
1. 最后一个参数是回调函数
31+
2. 回调函数的参数为 `(err, result)`,前面是可能的错误,后面是正常的结果
32+
33+
## 结合 Await/Async 使用
34+
35+
同样是上面的例子,如果想要结合 Await/Async,可以这样使用:
36+
37+
```javascript
38+
const util = require('util');
39+
const fs = require('fs');
40+
41+
const stat = util.promisify(fs.stat);
42+
async function readStats(dir) {
43+
try {
44+
let stats = await stat(dir);
45+
// Do something with `stats`
46+
} catch (err) { // Handle the error.
47+
console.log(err);
48+
}
49+
}
50+
readStats('.');
51+
```
52+
53+
## 自定义 Promise 化处理函数
54+
55+
那如果现有的使用回调的函数不符合这个风格,还能用 `util.promisify()` 么?答案也是肯定的。我们只要给函数增加一个属性 `util.promisify.custom`,指定一个函数作为 Promise 化处理函数,即可。请看下面的代码:
56+
57+
```javascript
58+
const util = require('util');
59+
60+
// 这就是要处理的使用回调的函数
61+
function doSomething(foo, callback) {
62+
// ...
63+
}
64+
65+
// 给它增加一个方法,用来在 Promise 化时调用
66+
doSomething[util.promisify.custom] = function(foo) {
67+
// 自定义生成 Promise 的逻辑
68+
return getPromiseSomehow();
69+
};
70+
71+
const promisified = util.promisify(doSomething);
72+
console.log(promisified === doSomething[util.promisify.custom]);
73+
// prints 'true'
74+
```
75+
76+
如此一来,任何时候我们对目标函数 doSomething 进行 Promise 化处理,都会得到之前定义的函数。运行它,就会按照我们设计的特定逻辑返回 Promise 对象。
77+
78+
有了 `util.promisify`,升级异步回到函数,使用 Promise 或者 Async 真的方便了很多。

Diff for: 04-upgrade.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
改进老代码
2+
========
3+
4+
学会新的异步操作之后,我们自然希望改造之前的异步回调代码。下面我就带领大家来试一试。
5+
6+
## 将回调包装成 Promise
7+
8+
这是最常见的应用。它有两个显而易见的好处:
9+
10+
1. 可读性更好
11+
2. 返回的结果可以加入任何 Promise 队列
12+
3. 可以使用 Await/Async
13+
14+
```javascript
15+
// FileSystem.js
16+
const fs = require('fs');
17+
18+
module.exports = {
19+
readFile: function (path, options) {
20+
return new Promise( resolve => {
21+
fs.readFile(path, options, (err, content) => {
22+
if (err) {
23+
throw err;
24+
}
25+
resolve(content);
26+
});
27+
});
28+
}
29+
};
30+
31+
// a.js
32+
const fs = require('./FileSystem');
33+
34+
fs.readFile('../README.md', 'utf-8')
35+
.then(content => {
36+
console.log(content);
37+
});
38+
```
39+
40+
## 将任何异步操作都包装成 Promise
41+

Diff for: 10-review.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33

44
## 参考阅读
55

6-
* [让微信小程序支持 ES6 的 Promise 特性](https://haojen.github.io/2016/11/23/wechat-app-promise/)
6+
* [让微信小程序支持 ES6 的 Promise 特性](https://haojen.github.io/2016/11/23/wechat-app-promise/)
7+
* [util.promisify() in Node.js v8](http://farzicoder.com/util-promisify-in-Node-js-v8/)
8+
* [util.promisify 官方文档](https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original)

Diff for: 20-2-old.md

Whitespace-only changes.

Diff for: README.md

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
1. 了解 JavaScript
1212
2. 最好有异步开发经验
1313

14+
## 约定
15+
16+
范例代码中会使用 ES6 的一些语法,也会混用 ES6 Modules/CommonJS。
17+
1418
## 作者介绍
1519

1620
大家好,我叫翟路佳,花名“肉山”,这个名字跟 Dota 没关系,从高中起伴随我到现在。

Diff for: SUMMARY.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
* [Promise 方案](02-promise-intro.md)
66
* [Promise 入门](02-1-promise-basic.md)
77
* [Promise 进阶](02-2-promise-advanced.md)
8-
* [Node.js 8 的新方法](02-3-node-js.md)
9-
* [Await/Async 方案](03-await-async-.md)
8+
* [Await/Async 方案](03-await-async-.md)
9+
* [改进老代码](04-upgrade.md)
1010
* [回顾](10-review.md)
11-
* [Tips:小程序](20-1-xiaochengxu.md)
12-
* [Tips:改进老代码](20-2old.md)
11+
* [Tips:小程序](20-1-xiaochengxu.md)

0 commit comments

Comments
 (0)