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) {
|
async function asyncPrint(value, ms) {
|
||||||
await timeout(ms);
|
await timeout(ms);
|
||||||
console.log(value)
|
console.log(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
asyncPrint('hello world', 50);
|
asyncPrint('hello world', 50);
|
||||||
@ -108,6 +108,23 @@ asyncPrint('hello world', 50);
|
|||||||
|
|
||||||
上面代码指定50毫秒以后,输出`hello world`。
|
上面代码指定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 函数有多种使用形式。
|
async 函数有多种使用形式。
|
||||||
|
|
||||||
```javascript
|
```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`代码块中。
|
第一点,前面已经说过,`await`命令后面的`Promise`对象,运行结果可能是`rejected`,所以最好把`await`命令放在`try...catch`代码块中。
|
||||||
|
@ -546,7 +546,7 @@ co(gen);
|
|||||||
|
|
||||||
上面代码中,Generator 函数只要传入`co`函数,就会自动执行。
|
上面代码中,Generator 函数只要传入`co`函数,就会自动执行。
|
||||||
|
|
||||||
`co`函数返回一个Promise对象,因此可以用`then`方法添加回调函数。
|
`co`函数返回一个`Promise`对象,因此可以用`then`方法添加回调函数。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
co(gen).then(function (){
|
co(gen).then(function (){
|
||||||
@ -568,7 +568,7 @@ co(gen).then(function (){
|
|||||||
|
|
||||||
(2)Promise 对象。将异步操作包装成 Promise 对象,用`then`方法交回执行权。
|
(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 模块必须的。
|
上一节已经介绍了基于 Thunk 函数的自动执行器。下面来看,基于 Promise 对象的自动执行器。这是理解 co 模块必须的。
|
||||||
|
|
||||||
@ -752,3 +752,41 @@ function* somethingAsync(x) {
|
|||||||
|
|
||||||
上面的代码允许并发三个`somethingAsync`异步操作,等到它们全部完成,才会进行下一步。
|
上面的代码允许并发三个`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`这个词出现的次数。
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ ES6 从开始制定到最后发布,整整用了15年。
|
|||||||
|
|
||||||
各大浏览器的最新版本,对 ES6 的支持可以查看[kangax.github.io/es5-compat-table/es6/](http://kangax.github.io/es5-compat-table/es6/)。随着时间的推移,支持度已经越来越高了,超过90%的 ES6 语法特性都实现了。
|
各大浏览器的最新版本,对 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
|
```bash
|
||||||
$ node --v8-options | grep harmony
|
$ node --v8-options | grep harmony
|
||||||
|
@ -94,7 +94,7 @@ ES5通过下面的代码,部署`Number.isNaN()`。
|
|||||||
})(this);
|
})(this);
|
||||||
```
|
```
|
||||||
|
|
||||||
它们与传统的全局方法`isFinite()`和`isNaN()`的区别在于,传统方法先调用`Number()`将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,isFinite对于非数值一律返回`false`, isNaN只有对于NaN才返回`true`,非NaN一律返回`false`。
|
它们与传统的全局方法`isFinite()`和`isNaN()`的区别在于,传统方法先调用`Number()`将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,`Number.isFinite()`对于非数值一律返回`false`, `Number.isNaN()`只有对于`NaN`才返回`true`,非`NaN`一律返回`false`。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
isFinite(25) // true
|
isFinite(25) // true
|
||||||
|
@ -193,6 +193,32 @@ Reflect.set(1, 'foo', {}) // 报错
|
|||||||
Reflect.set(false, '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(obj, name)
|
||||||
|
|
||||||
`Reflect.has`方法对应`name in obj`里面的`in`运算符。
|
`Reflect.has`方法对应`name in obj`里面的`in`运算符。
|
||||||
|
Loading…
x
Reference in New Issue
Block a user