在阅读(强烈推荐)丛书You Don't Know JS的同时,我阅读了this部分:
function foo(x,y,cb) {
ajax(
"http://some.url.1/?x=" + x + "&y=" + y,
cb
);
}
foo( 11, 31, function(err,text) {
if (err) {
console.error( err );
}
else {
console.log( text );
}
} );
您可以清楚地看到,wiki definition对函数foo
的调用是完全异步的:
在计算机编程中,异步是指独立于主程序流程和处理此类事件的方式而发生的事件。这些可能是“外部”事件,例如信号的到来,或与程序执行同时发生的由程序引发的动作, 没有程序阻塞等待结果
作者使用generators
重新实现了以上代码,以演示我们要执行异步功能时如何使用generators
:
function foo(x,y) {
ajax(
"http://some.url.1/?x=" + x + "&y=" + y,
function(err,data){
if (err) {
// throw an error into `*main()`
it.throw( err );
}
else {
// resume `*main()` with received `data`
it.next( data );
}
}
);
}
function *main() {
try {
var text = yield foo( 11, 31 );
console.log( text );
}
catch (err) {
console.error( err );
}
}
var it = main();
// start it all up!
it.next();
通过调用it.next()
,我们执行main
直到第一个yield
,然后等待直到迭代器it
将恢复main
执行。根据异步的定义,以下代码段的调用不是异步的:
function *main() {
try {
var text = yield foo( 11, 31 );
console.log( text );
}
catch (err) {
console.error( err );
}
}
并且:
var it = main();
// start it all up!
it.next();
我的任何结论不正确吗?
答案 0 :(得分:3)
我是YDKJS的作者。运行的第一个it.next()
调用(第二个片段的最后一行)确实是 synchronous (同步),但文本没有另外声明。而是像在第一个引用的代码段中一样,该文本断言第二个it.next(..)
调用是异步的。
代码假定ajax(..)
调用实际上是异步进行的,因此其响应(调用该回调)也是异步的。因此,it.next(..)
的第二次调用(恢复已暂停的yield foo(..)
调用的调用)实际上是在异步中发生的。
换句话说,yield foo(..)
在Ajax调用过程中在本地暂停该生成器,这允许其余JS程序中的任何一个运行,并且当Ajax响应返回时,{{1} }调用将恢复生成器...异步。
希望可以解决所有问题。