以下代码是否异步?

时间:2018-07-20 22:47:27

标签: javascript asynchronous generator

在阅读(强烈推荐)丛书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();

我的任何结论不正确吗?

1 个答案:

答案 0 :(得分:3)

我是YDKJS的作者。运行的第一个it.next()调用(第二个片段的最后一行)确实是 synchronous (同步),但文本没有另外声明。而是像在第一个引用的代码段中一样,该文本断言第二个it.next(..)调用是异步的。

代码假定ajax(..)调用实际上是异步进行的,因此其响应(调用该回调)也是异步的。因此,it.next(..)的第二次调用(恢复已暂停的yield foo(..)调用的调用)实际上是在异步中发生的。

换句话说,yield foo(..)在Ajax调用过程中在本地暂停该生成器,这允许其余JS程序中的任何一个运行,并且当Ajax响应返回时,{{1} }调用将恢复生成器...异步。

希望可以解决所有问题。