nodejs之yield 和 yield*
阿新 • • 發佈:2019-01-30
1.普通的yield
function* outer(){
yield 'begin';
yield inner();
yield 'end';
}
function* inner(){
yield 'inner';
}
var it = outer(),v;
v= it.next().value;
console.log(v);
v= it.next().value;
console.log(v);
console.log(v.toString());
v = it.next().value;
console.log(v);
輸出
➜ qiantou node yiely02.js
begin
{}
[object Generator]
end
2.代理yield
➜ qiantou cat yield05.js
function* outer(){
yield 'begin';
var ret = yield* inner();
console.log(ret);
yield 'end';
}
function * inner(){
yield 'inner';
return 'return from inner';
}
var it = outer(),v;
v = it.next().value;
console.log(v);
v = it.next().value;
console.log(v);
v = it.next().value;
console.log(v)
輸出
➜ qiantou node yield05.js
begin
inner
return from inner
end
yield* 後面接受一個 iterable object 作為引數,然後去迭代(iterate)這個迭代器(iterable object),同時 yield* 本身這個表示式的值就是迭代器迭代完成時(done: true)的返回值。呼叫 generator function 會返回一個 generator object,這個物件本身也是一種 iterable object,所以,我們可以使用 yield* generator_function() 這種寫法。
yield 是為了解決 node.js 非同步回撥問題,主要是寫法上的同步
3.yield 和 co
➜ qiantou cat co01.js
var co = require('co');
co(function* (){
var a = yield Promise.resolve(1);
console.log(a);
var b = yield later(10);
console.log(b);
var c = yield fn;
console.log(c);
var d = yield fn(5);
console.log(d);
var e = yield [
Promise.resolve('a'),
later('b'),
fn,
fn(5)
];
console.log(e);
var f = yield{
'a':Promise.resolve('a'),
'b':later('b'),
'c':fn,
'd':fn(5)
};
console.log(f);
function* fn(n){
n = n || 1;
var a = yield later(n);
return 'fn_'+ a;
}
function later(n,t){
t = t || 1000;
return function(done){
setTimeout(function(){done(null,n)},t);
};
}
}).catch(function(e){
console.error(e);
});
輸出
➜ qiantou node co01.js
1
10
fn_1
fn_5
[ 'a', 'b', 'fn_1', 'fn_5' ]
{ a: 'a', b: 'b', c: 'fn_1', d: 'fn_5' }
yield* 的作用
用原生語法,拋棄 co 的黑魔法,換取一點點點點效能提升
明確表明自己的意圖,避免混淆
呼叫時保證正確的 this 指向