1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 10:22:23 +00:00

docs: edit number.isFinite

This commit is contained in:
ruanyf 2017-03-28 19:46:30 +08:00
parent f969d88ef3
commit d51beedbd6
5 changed files with 111 additions and 8 deletions

View File

@ -100,7 +100,7 @@ function timeout(ms) {
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value)
console.log(value);
}
asyncPrint('hello world', 50);
@ -108,6 +108,23 @@ asyncPrint('hello world', 50);
上面代码指定50毫秒以后输出`hello world`
由于`async`函数返回的是 Promise 对象,可以作为`await`命令的参数。所以,上面的例子也可以写成下面的形式。
```javascript
async function timeout(ms) {
await new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value);
}
asyncPrint('hello world', 50);
```
async 函数有多种使用形式。
```javascript
@ -315,6 +332,28 @@ async function main() {
}
```
下面的例子使用`try...catch`结构,实现多次重复尝试。
```javascript
const superagent = require('superagent');
const NUM_RETRIES = 3;
async function test() {
let i;
for (i = 0; i < NUM_RETRIES; ++i) {
try {
await superagent.get('http://google.com/this-throws-an-error');
break;
} catch(err) {}
}
console.log(i); // 3
}
test();
```
上面代码中,如果`await`操作成功,就会使用`break`语句退出循环;如果失败,会被`catch`语句捕捉,然后进入下一轮循环。
### 使用注意点
第一点,前面已经说过,`await`命令后面的`Promise`对象,运行结果可能是`rejected`,所以最好把`await`命令放在`try...catch`代码块中。

View File

@ -544,9 +544,9 @@ var co = require('co');
co(gen);
```
上面代码中Generator函数只要传入`co`函数,就会自动执行。
上面代码中Generator 函数只要传入`co`函数,就会自动执行。
`co`函数返回一个Promise对象因此可以用`then`方法添加回调函数。
`co`函数返回一个`Promise`对象,因此可以用`then`方法添加回调函数。
```javascript
co(gen).then(function (){
@ -568,7 +568,7 @@ co(gen).then(function (){
2Promise 对象。将异步操作包装成 Promise 对象,用`then`方法交回执行权。
co 模块其实就是将两种自动执行器Thunk 函数和 Promise 对象),包装成一个模块。使用 co 的前提条件是Generator 函数的`yield`命令后面,只能是 Thunk 函数或 Promise 对象。如果数组或对象的成员,全部都是 Promise 对象,也是可以的详见后文的例子。4.0 版以后,`yield`命令后面只能是 Promise 对象。)
co 模块其实就是将两种自动执行器Thunk 函数和 Promise 对象),包装成一个模块。使用 co 的前提条件是Generator 函数的`yield`命令后面,只能是 Thunk 函数或 Promise 对象。如果数组或对象的成员,全部都是 Promise 对象,也可以使用 co详见后文的例子。co v4.0版以后,`yield`命令后面只能是 Promise 对象,不再支持 Thunk 函数。)
上一节已经介绍了基于 Thunk 函数的自动执行器。下面来看,基于 Promise 对象的自动执行器。这是理解 co 模块必须的。
@ -752,3 +752,41 @@ function* somethingAsync(x) {
上面的代码允许并发三个`somethingAsync`异步操作,等到它们全部完成,才会进行下一步。
### 实例:处理 Stream
Node 提供 Stream 模式读写数据特点是一次只处理数据的一部分数据分成一块块依次处理就好像“数据流”一样。这对于处理大规模数据非常有利。Stream 模式使用 EventEmitter API会释放三个事件。
- `data`事件:下一块数据块已经准备好了。
- `end`事件:整个“数据流”处理“完了。
- `error`事件:发生错误。
使用`Promise.race()`函数,可以判断这三个事件之中哪一个最先发生,只有当`data`时间最先发生时,才进入下一个数据块的处理。从而,通过一个`while`循环,完成所有数据的读取。
```javascript
const co = require('co');
const fs = require('fs');
const stream = fs.createReadStream('./les_miserables.txt');
let valjeanCount = 0;
co(function*() {
while(true) {
const res = yield Promise.race([
new Promise(resolve => stream.once('data', resolve)),
new Promise(resolve => stream.once('end', resolve)),
new Promise((resolve, reject) => stream.once('error', reject))
]);
if (!res) {
break;
}
stream.removeAllListeners('data');
stream.removeAllListeners('end');
stream.removeAllListeners('error');
valjeanCount += (res.toString().match(/valjean/ig) || []).length;
}
console.log('count:', valjeanCount); // count: 1120
});
```
上面代码采用 Stream 模式读取《悲惨世界》的文本文件,对于每个数据块都使用`stream.once`方法,在`data``end``error`三个事件上添加一次性回调函数。变量`res`只有在`data`事件发生时,才有值。然后,累加每个数据块之中`valjean`这个词出现的次数。

View File

@ -48,9 +48,9 @@ ES6 的第一个版本就这样在2015年6月发布了正式名称就是
ES6 从开始制定到最后发布整整用了15年。
前面提到ECMAScript 1.0是1997年发布的接下来的两年连续发布了 ECMAScript 2.01998年6月和 ECMAScript 3.01999年12月。3.0版是一个巨大的成功,在业界得到广泛支持,成为通行标准,奠定了 JavaScript 语言的基本语法,以后的版本完全继承。直到今天,初学者一开始学习 JavaScript其实就是在学3.0版的语法。
前面提到ECMAScript 1.0 是1997年发布的接下来的两年连续发布了 ECMAScript 2.01998年6月和 ECMAScript 3.01999年12月。3.0版是一个巨大的成功,在业界得到广泛支持,成为通行标准,奠定了 JavaScript 语言的基本语法,以后的版本完全继承。直到今天,初学者一开始学习 JavaScript其实就是在学3.0版的语法。
2000年ECMAScript 4.0开始酝酿。这个版本最后没有通过,但是它的大部分内容被 ES6 继承了。因此ES6 制定的起点其实是2000年。
2000年ECMAScript 4.0 开始酝酿。这个版本最后没有通过,但是它的大部分内容被 ES6 继承了。因此ES6 制定的起点其实是2000年。
为什么 ES4 没有通过呢?因为这个版本太激进了,对 ES3 做了彻底升级导致标准委员会的一些成员不愿意接受。ECMA 的第39号技术专家委员会Technical Committee 39简称TC39负责制订 ECMAScript 标准,成员包括 Microsoft、Mozilla、Google 等大公司。
@ -72,7 +72,7 @@ ES6 从开始制定到最后发布整整用了15年。
各大浏览器的最新版本,对 ES6 的支持可以查看[kangax.github.io/es5-compat-table/es6/](http://kangax.github.io/es5-compat-table/es6/)。随着时间的推移支持度已经越来越高了超过90%的 ES6 语法特性都实现了。
Node 是 JavaScript 的服务器运行环境runtime。它对 ES6 的支持更高。除了那些默认打开的功能,还有一些语法功能已经实现了,但是默认没有打开。使用下面的命令,可以查看 Node 那些没有打开的 ES6 特性。
Node 是 JavaScript 的服务器运行环境runtime。它对 ES6 的支持更高。除了那些默认打开的功能,还有一些语法功能已经实现了,但是默认没有打开。使用下面的命令,可以查看 Node 已经实现的 ES6 特性。
```bash
$ node --v8-options | grep harmony

View File

@ -94,7 +94,7 @@ ES5通过下面的代码部署`Number.isNaN()`。
})(this);
```
它们与传统的全局方法`isFinite()``isNaN()`的区别在于,传统方法先调用`Number()`将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,isFinite对于非数值一律返回`false`, isNaN只有对于NaN才返回`true`,非NaN一律返回`false`
它们与传统的全局方法`isFinite()``isNaN()`的区别在于,传统方法先调用`Number()`将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,`Number.isFinite()`对于非数值一律返回`false`, `Number.isNaN()`只有对于`NaN`才返回`true`,非`NaN`一律返回`false`
```javascript
isFinite(25) // true

View File

@ -193,6 +193,32 @@ Reflect.set(1, 'foo', {}) // 报错
Reflect.set(false, 'foo', {}) // 报错
```
注意,`Reflect.set`会触发`Proxy.defineProperty`拦截。
```javascript
let p = {
a: 'a'
};
let handler = {
set(target,key,value,receiver) {
console.log('set');
Reflect.set(target,key,value,receiver)
},
defineProperty(target, key, attribute) {
console.log('defineProperty');
Reflect.defineProperty(target,key,attribute);
}
};
let obj = new Proxy(p, handler);
obj.a = 'A';
// set
// defineProperty
```
上面代码中,`Proxy.set`拦截中使用了`Reflect.set`,导致触发`Proxy.defineProperty`拦截。
### Reflect.has(obj, name)
`Reflect.has`方法对应`name in obj`里面的`in`运算符。