mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-24 18:32:22 +00:00
docs: edit number.isFinite
This commit is contained in:
parent
f969d88ef3
commit
d51beedbd6
@ -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`代码块中。
|
||||
|
@ -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 (){
|
||||
|
||||
(2)Promise 对象。将异步操作包装成 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`这个词出现的次数。
|
||||
|
||||
|
@ -48,9 +48,9 @@ ES6 的第一个版本,就这样在2015年6月发布了,正式名称就是
|
||||
|
||||
ES6 从开始制定到最后发布,整整用了15年。
|
||||
|
||||
前面提到,ECMAScript 1.0是1997年发布的,接下来的两年,连续发布了 ECMAScript 2.0(1998年6月)和 ECMAScript 3.0(1999年12月)。3.0版是一个巨大的成功,在业界得到广泛支持,成为通行标准,奠定了 JavaScript 语言的基本语法,以后的版本完全继承。直到今天,初学者一开始学习 JavaScript,其实就是在学3.0版的语法。
|
||||
前面提到,ECMAScript 1.0 是1997年发布的,接下来的两年,连续发布了 ECMAScript 2.0(1998年6月)和 ECMAScript 3.0(1999年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
|
||||
|
@ -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
|
||||
|
@ -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`运算符。
|
||||
|
Loading…
x
Reference in New Issue
Block a user