You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MDN上还有一句话我觉得对理解定义有帮助:It is not possible to know reflectively whether a particular object implements the iterator protocol
生成器(Generator)
The Generator object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol.
那什么是generator function?
Generator functions are written using the function* syntax. When called initially, generator functions do not execute any of their code, instead returning a type of iterator called a Generator.
function* 这种语法是生成器函数。我们调用了之后会返回一个Generator。这个Generator是个iterator。
生成器函数每次被调用都会生成一个新的Generator,这个Generator只能被迭代一次。
注意:不能用箭头函数创建生成器
让我们写一个generator function:
function * foo (){
let a = yield 1
console.log(a)
let b = yield 2
console.log(b)
let c = yield 3
console.log(c)
}
let g = foo()
g.next(111) --> {value: 1, done: false} //注意!第一次next传参是没用的!
g.next(222) --> 222 {value: 2, done: false}
g.next(333) --> 333 {value: 3, done: false}
g.next(444) --> 444 {value: undefined, done: true}
g.next(555) --> {value: undefined, done: true}
g.next(666) --> {value: undefined, done: true}
g.next(777) --> {value: undefined, done: true}
g.next(888) --> {value: undefined, done: true}
g.next(999) --> {value: undefined, done: true}
这样我们就看到了生成器的另一个很有用的功能,我们可以通过next给传参数,进行异步填充值。
实现简单的异步
想象下有下面这样的代码:
function makeAjaxCall(url,cb) {
// do some ajax fun
// call `cb(result)` when complete
}
makeAjaxCall( "http://some.url.1", function(result1){
makeAjaxCall( "http://some.url.2/?id=" + result1.id, function(result2){
console.log( "The value you asked for: " +result2 );
});
} );
使用generator(不需要额外的修饰)来表达相同的程序,你可以这么写:
function request(url) {
// this is where we're hiding the asynchronicity,
// away from the main code of our generator
// `it.next(..)` is the generator's iterator-resume
// call
makeAjaxCall( url, function(response){
it.next( response );
} );
// Note: nothing returned here!
}
function *main() {
var result1 = yield request( "http://some.url.1" );
var result2 = yield request( "http://some.url.2?id=" + result1.id );
console.log( "The value you asked for: " + result2 );
}
var it = main();
it.next(); // get it all started
我写了一个setTimeOut模拟的,可能会大家的理解有帮助。
function request(url) {
setTimeout(() => {
it.next( url );
}, 2000);
}
function *main() {
var result1 = yield request( "url1" );
console.log(result1)
var result2 = yield request( "url2" + result1 );
console.log( "The value you asked for: " + result2 );
}
var it = main();
it.next()
The text was updated successfully, but these errors were encountered:
前言
这次原定主题是《异步模式的发展》应该会分为四部分:
我觉得大家如果不常用Generator的语法的话,可能会忘记了,而且Generator确实是值得拿出来单独分享一次。这次先分享这个《用Generator实现异步》。分享过之后才可能串起来js的异步模式是怎么发展的。
用Generator实现异步
语法回顾
迭代器(Iterator)
我们先说什么是迭代器:凡是符合迭代器协议的,都叫迭代器。
那么什么是迭代器协议?我从mdn上截图了。
意思就是说:
在 JavaScript 中 迭代器是一个对象,它提供了一个next() 方法,用来返回一个结果对象。这个结果对象包含两个属性:done和 value。
让我们手撕一个迭代器:
MDN上还有一句话我觉得对理解定义有帮助:It is not possible to know reflectively whether a particular object implements the iterator protocol
生成器(Generator)
The Generator object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol.
那什么是generator function?
Generator functions are written using the function* syntax. When called initially, generator functions do not execute any of their code, instead returning a type of iterator called a Generator.
function* 这种语法是生成器函数。我们调用了之后会返回一个Generator。这个Generator是个iterator。
生成器函数每次被调用都会生成一个新的Generator,这个Generator只能被迭代一次。
注意:不能用箭头函数创建生成器
让我们写一个generator function:
我们可以看到以上代码非常容易的就做到了暂停执行,然后通过调用next又能继续执行了。让我们来给next传一点参数进去。
这样我们就看到了生成器的另一个很有用的功能,我们可以通过next给传参数,进行异步填充值。
实现简单的异步
想象下有下面这样的代码:
使用generator(不需要额外的修饰)来表达相同的程序,你可以这么写:
我写了一个setTimeOut模拟的,可能会大家的理解有帮助。
The text was updated successfully, but these errors were encountered: