使用`.bind`将必要的数据附加到异步操作的回调处理程序是一种好的做法吗?

时间:2015-09-04 21:39:29

标签: javascript asynchronous callback bind

在JavaScript中异步工作并与第三方代码交互时(特别是在Node的情况下),没有标准方法来定义所需数据如何传递到下一个函数。有些东西可以在某些情况下提供帮助,例如async和Promises,但这些东西可能会使事情变得更加复杂,并且不会处理主要问题,即在请求期间跟踪先决条件数据。这导致代码如下:

function tryLogin(username, password, callback) {
    // Variables possibly defined here while sanitizing data
    thirdPartyLogin(username, password, function(err) {
        if(err) return callback(err, null);
        // Perform internal login actions here
        callback(null, new Session(username));
        });
    }

它看起来很简单,而且很简单,但它有几个问题:

  • 它为每个调用创建一个全新的函数,可以使应用程序效率降低。
  • 回调树下的每个变量都会保留每个函数使用的每个变量,一直到树中调用的根函数。
  • 如果回调丢失或被第三方插件占用导致该插件中的内存泄漏,则将包含所有这些数据。
  • 长分支可以使代码更难阅读,更少组织

但是,虽然稍微复杂一点,但在这样的回调中使用.bind会有所帮助:

var tryLogin = (function(){
    var start = function(username, password, callback) {
        // Sanitizing data
        thirdPartyLogin(username, password,
            afterLoginAttempted.bind({u: username, c: callback})
            );
        },
    afterLoginAttempted = function(err) {
        if(err) return this.c(err, null);
        // Perform internal login actions here
        this.c(null, new Session(this.u));
        };
    return start;
    }());

这有以下好处:

  • 在每次调用时创建的新函数是一个本机虚函数,除了与其绑定的对象之外几乎不占用任何内容
  • 清理数据时定义的变量可以立即从一个函数到下一个函数进行垃圾收集。
  • 如果回调丢失或被第三方插件保留,则只包含所需的必要数据
  • 通过允许更加同步的编程风格(从上到下,下一个函数通常可以直接在它被调用的地方找到)来防止长分支并允许更复杂的代码更容易阅读。

我问,因为我从来没有见过bind在我自己以外的任何作品中使用var em1 = document.getElementById("em1"); var em2 = document.getElementById("em2"); var emHint = document.getElementById("emHint"); em1.addEventListener("keyup", function(){match_handler(em1, em2, emHint);}); em1.addEventListener("focus", function(){match_handler(em1, em2, emHint);}); em1.addEventListener("blur", function(){match_handler(em1, em2, emHint);}); em2.addEventListener("keyup", function(){match_handler(em1, em2, emHint);}); em2.addEventListener("focus",function(){match_handler(em1, em2, emHint);}); em2.addEventListener("blur", function(){match_handler(em1, em2, emHint);}); function match_handler(field_one, field_two, text_hint){ if (field_one.value != field_two.value) { text_hint.style.display = "block"; } else { text_hint.style.display = "none"; } } ,我觉得好像我可能是唯一一个。所以如果有人有更好的建议,我想知道。或者,如果这是一个很酷的新想法,请告诉我。我很乐意接受评论和批评,但最重要的是我真的只想知道更有经验的程序员对此的看法。

0 个答案:

没有答案