做网站编辑前景,wordpress php.ini路径,公司注册网站需要什么资料,网络运维工程师的月薪有多少Generator 种异步编程解决方案 函数会返回一个遍历器对象语法上:Generator 函数是一个状态机#xff0c;封装了多个内部状态。形式上:Generator 函数是一个普通函数;有两个特征。一是#xff0c;function关键字与函数名之间有一个星号#xff1b;二是#xff0c;函数体内部…Generator 种异步编程解决方案 函数会返回一个遍历器对象语法上:Generator 函数是一个状态机封装了多个内部状态。形式上:Generator 函数是一个普通函数;有两个特征。一是function关键字与函数名之间有一个星号二是函数体内部使用yield表达式
function* helloWorldGenerator() {yield hello;yield world;return ending;
}
var hw helloWorldGenerator();它内部有两个yield表达式hello和world即该函数有三个状态helloworld 和 return 语句结束执行。 调用 Generator 函数后该函数并不执行返回的也不是函数运行结果而是一个指向内部状态的指针对象也就是上一章介绍的遍历器对象Iterator Object。
总结一下
调用 Generator 函数返回一个遍历器对象代表 Generator 函数的内部指针。以后每次调用遍历器对象的next方法就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值是yield表达式后面那个表达式的值done属性是一个布尔值表示是否遍历结束。
yield 表达式 遍历器对象的next方法的运行逻辑如下。 yield表达式是暂停执行的标记而next方法可以恢复执行。 yield表达式后面的表达式只有当调用next方法、内部指针指向该语句时才会执行;“惰性求值” yield表达式只能用在 Generator 函数里面用在其他地方都会报错。 遇到yield表达式就暂停执行后面的操作并将紧跟在yield后面的那个表达式的值作为返回的对象的value属性值。下一次调用next方法时再继续往下执行直到遇到下一个yield表达式。如果没有再遇到新的yield表达式就一直运行到函数结束直到return语句为止并将return语句后面的表达式的值作为返回的对象的value属性值。
yield表达式如果用在另一个表达式之中必须放在圆括号里面。
function* demo() {console.log(Hello (yield)); // OKconsole.log(Hello (yield 123)); // OK
}yield表达式用作函数参数或放在赋值表达式的右边可以不加括号。
function* demo() {foo(yield a, yield b); // OKlet input yield; // OK
}与 Iterator 接口的关系 由于 Generator 函数就是遍历器生成函数,因此可以把 Generator 赋值给对象的Symbol.iterator属性 含义Generator 与状态机
没懂协程与子例程
next() 方法 yield表达式本身没有返回值 undefined next方法可以带一个参数该参数就会被当作上一个yield表达式的返回值。
function* f() {let a 2 * (yield 1) // 2 * undefindconsole.log(a:, a) //NaNlet b 2 * (yield 2)console.log(a, b)//NaN, 20return 1
}
let a f()
console.log(a.next())//{value: 1, done: false}
console.log(a.next())//{value: 2, done: false}
console.log(a.next(10))//{value: 1, done: true}for…of 循环
yied*表达式 在 Generator 函数内部调用另一个 Generator 函数。需要在前者的函数体内部自己手动完成遍历。 function* foo() { yield a; yield b; }
function* bar() {yield x;for (let i of foo()) {yield i}; yield y;
}
for (let v of bar()){ console.log(v); }在 Generator 函数内部调用另一个 Generator 函数。需要在前者的函数体内部自己手动完成遍历。提供了yield*表达式作为解决办法用来在一个 Generator 函数里面执行另一个 Generator 函数。
function* bar() { yield x; yield* foo(); yield y; }
// 等同于
function* bar() { yield x; yield a; yield b; yield y; }语法角度如果yield表达式后面跟的是一个遍历器对象需要在yield表达式后面加上星号表明它返回的是一个遍历器对象。这被称为yield*表达式。 如果yield*后面跟着一个数组由于数组原生支持遍历器因此就会遍历数组成员。
function* gen(){ yield* [a, b, c]}
gen().next() // { value:a, done:false }let read (function* () {yield hello;yield* hello;
})();
read.next().value // hello
read.next().value // h如果被代理的 Generator 函数有return语句,结果是不一样的‘
function* foo() { yield a; yield b; }
function* bar() {yield x;for (let i of foo()) {yield i}; yield y;
}
for (let v of bar()){ console.log(v); }throw throw指针对象的throw方法抛出的错误可以被函数体内的try...catch代码块捕获。 function* gen(x){try {var y yield x 2;} catch (e){console.log(e);}return y;
}
var g gen(1);
g.next();
g.throw(出错了);
// 出错了出错的代码与处理错误的代码实现了时间和空间上的分离这对于异步编程无疑是很重要的。 Thunk 函数
**传值调用:**即在进入函数体之前就计算x 5的值
f(x 5)
// 传值调用时等同于
f(6)传名调用:
f(x 5)
// 传名调用时等同于
(x 5) * 2两种比较
传值调用比较简单但是对参数求值的时候实际上还没用到这个参数有可能造成性能损失。
Thunk 函数的含义 编译器的“传名调用”实现往往是将参数放到一个临时函数之中再将这个临时函数传入函数体。这个临时函数就叫做 Thunk 函数。 function f(m) {return m * 2;
}
f(x 5);
// 等同于
var thunk function () {return x 5;
};
function f(thunk) {return thunk() * 2;
}JavaScript 语言是传值调用它的 Thunk 函数含义有所不同。在 JavaScript 语言中Thunk 函数替换的不是表达式而是多参数函数将其替换成一个只接受回调函数作为参数的单参数函数。这个单参数版本就叫做 Thunk 函数。
// 正常版本的readFile多参数版本
fs.readFile(fileName, callback);
// Thunk版本的readFile单参数版本
var Thunk function (fileName) {return function (callback) {return fs.readFile(fileName, callback);};
};
var readFileThunk Thunk(fileName);
readFileThunk(callback);thunk函数
不会
co模块
不会