遍历器对象除了具有next方法,还可以具有return方法和throw方法。如果你自己写遍历器对象生成函数,那么next方法是必须部署的,return方法和throw方法是否部署是可选的。
return方法的使用场合是,如果for…of循环提前退出(通常是因为出错,或者有break语句),就会调用return方法。如果一个对象在完成遍历前,需要清理或释放资源,就可以部署return方法。
如下是代码示例:
var fs = require("fs");
var readLine = require("readline");
/**
* 按行读取文件内容
*
* @param fReadName 文件名路径
* @param cb 回调函数
*
* @return 字符串数组
*/
function readFileToArr(fReadName, cb) {
var arr = [];
var readObj = readLine.createInterface({
input: fs.createReadStream(fReadName)
});
readObj.on('line', function (line) {
arr.push(line);
});
readObj.on('close', function () {
console.log('readLine close....');
cb(arr);
});
}
function readLinesSync(data) {
return {
[Symbol.iterator]() {
let i = 0;
return {
next(){
return {value: data[i++], done: false};
},
return(){
console.log("-----------return-------");
return {done: true};
}
}
}
};
}
如下两种方法都会触发调用 iterator 中的 return 方法:
//方式一:
readFileToArr('ObserverMode.js', function (arr) {
let obj = readLinesSync(arr);
let i = 0;
for (let v of obj) {
console.log(v);
if (i++ == 10) {
break;
}
}
});
//方式二:
readFileToArr('ObserverMode.js', function (arr) {
let obj = readLinesSync(arr);
let i = 0;
for (let v of obj) {
console.log(v);
if (i++ == 10) {
throw new Error('Error--');
}
}
});
注意,return方法必须返回一个对象,这是 Generator 规格决定的。
如下是执行结果:
readLine close....
const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
const observable = obj => new Proxy(obj, {set});
function set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
queuedObservers.forEach(observer => observer());
return result;
}
-----------return-------
ObserverMode.js 的内容如下:
const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
const observable = obj => new Proxy(obj, {set});
function set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
queuedObservers.forEach(observer => observer());
return result;
}
const person = observable({
name: '张三',
age: 20
});
function print() {
console.log(`${person.name}, ${person.age}`)
}
observe(print);
person.name = '李四';