javascript - 强制回调异步

标签 javascript

所以我正在使用 this了解 JS 中异步行为的指南。我无法理解的例子是这个

function asyncify(fn) {
    var orig_fn = fn,
        intv = setTimeout( function(){
            intv = null;
            if (fn) fn();
        }, 0 )
    ;

    fn = null;

    return function() {
        // firing too quickly, before `intv` timer has fired to
        // indicate async turn has passed?
        if (intv) {
            fn = orig_fn.bind.apply(
                orig_fn,
                // add the wrapper's `this` to the `bind(..)`
                // call parameters, as well as currying any
                // passed in parameters
                [this].concat( [].slice.call( arguments ) )
            );
        }
        // already async
        else {
            // invoke original function
            orig_fn.apply( this, arguments );
        }
    };
}

用法:

function result(data) {
    console.log( a );
}

var a = 0;

ajax( "..pre-cached-url..", asyncify( result ) );
a++;

所以从概念上讲,我理解它试图强制一个将立即执行的函数在事件循环的下一个节拍上运行,这允许将变量 a 设置为值 1,因此将始终打印 1。

setTimeout 部分是我推测的部分,它将调用推送到事件循环的下一个滴答。但是,我完全迷失在代码的返回部分。

Q) 我知道 intv 将是计时器 ID,orgin_fn.bind.apply 的黑魔法到底是什么意思。我知道 bind,ahem 将一个值绑定(bind)到一个稍后调用的函数,apply 传递一个 this 对象和参数数组,但我很难理解整个调用流程,而且我从未见过 fb.bind.apply。

问)当我在浏览器中运行代码时,此对象解析为窗口,为什么所有参数都连接在窗口(在本例中为全局)对象上。

问)我知道这是 POC,但是是否有合理的理由在这里有一个 else block 来以任何方式执行函数。在哪种情况下我会看到它正在执行。

干杯!

最佳答案

orig_fn.bind.apply 用于替换同步回调。它正在创建一个新函数,该函数在被调用时将使用相同的 this 和调用它(替换)的参数调用原始函数,并将该函数分配给 fn .这是为了稍后当计时器关闭并调用 fn 时,它会使用正确的 this 和参数调用原始函数。 (参见 Function#bindFunction#apply ;棘手的一点是它在 bind 本身上使用 apply ,将 orig_fn 作为 this 用于 bind 调用。)

if/else 是这样的,如果在计时器关闭之前调用替换(intv 为真),它不会t 立即调用 orig_fn,它等待执行上述操作并将结果分配给 fn。但是,如果计时器已关闭(intvnull,因此为 falsy),它会立即同步调用原始函数。

通常,您不会希望创建一个像那样困惑的函数(有时异步执行某事,有时同步执行),但在这种特殊情况下,原因是它确保它包装的函数是 总是 异步调用:如果在调用 asyncify 时在同一个作业/任务*期间调用该函数,它会等待调用原始函数,直到计时器触发;但如果它已经在执行不同的工作/任务,它会立即执行。

该函数的更现代版本可能会使用 promise ,因为在当前环境中, promise 结算回调会在当前作业之后尽快发生;在浏览器上,这意味着它发生在定时器回调之前。 (Promise 结算回调是所谓的“微任务”与计时器和事件“宏任务”。在宏任务期间安排的任何微任务在该宏任务完成时执行,先于任何先前安排的下一个宏任务。)


* 工作 = JavaScript terminology , 任务 = browser terminology

关于javascript - 强制回调异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47164303/

相关文章:

javascript - 使用书架查询

php - 处理二维码生成器服务器端并存储在数据库中的库?

javascript - 动态使用 iframe 作为页面覆盖

javascript - 在没有更改 href 详细信息的链接上单击(Ctrl + 单击)时停止打开新选项卡

javascript - 使用 Bootstrap 将鼠标悬停在菜单上时显示子菜单下的子菜单

javascript - 简单的 jQuery 句柄处理

javascript - 当元素通过 ngIf 变得可见时触发事件

javascript - 在 Angular 中通过复选框过滤项目

Javascript XOR 运算(试图理解!)

javascript - 如何在 css/javascript 中制作模态高亮