保持在代码中看到这种模式,但在google或SO中找不到任何引用,很奇怪。有人能指点我参考this.async()函数吗?
var done = this.async();
// ...
$.get(path, function(contents) { // or some other function with callback
// ...
done(JST[path] = tmpl);
})
这是一种解决this
逃避内部回调问题的方法。如果没有这个额外的引用,代码将如下所示:
$.get(path, function(contents) { // or some other function with callback
//Wrong! `this` might no longer point to your object
this.done(JST[path] = tmpl);
})
不幸!内部响应回调中的this
与this
不同。实际上它可以是任何东西,取决于$.get
(调用回调使用)决定它。大多数人使用名为that
的额外引用用于相同的目的:
var that = this;
// ...
$.get(path, function(contents) { // or some other function with callback
// ...
that.async(JST[path] = tmpl);
})
这种模式似乎也合理且可读。
哦,如果你对这种语法感到好奇:
done(JST[path] = tmpl)
这是一个用作表达式的赋值。赋值是右边的,所以这段代码相当于:
JST[path] = tmpl;
done(tmpl);
var done = this.async()
和done(blah)
是一个聪明的技巧,可以在同步函数中返回从异步调用(例如$.get
)获取的值。
我们来看一个例子:
var getText = function() {
return "hello";
};
var text = getText();
这是一个非常简单的函数调用,所以这里没有谜题。但是,如果需要在getText()函数中异步获取文本,该怎么办?
var getText = function() {
return $.get('<some-url>', function(text) {
return text;
}); // ??????
};
致电getText()
不会返回您想要的文本。它返回jquery的promise对象。
那么我们如何使getText()
返回它从$.get()
调用获得的文本?
var getText = function() {
var done = this.async();
$.get('<some-url>', function(text) {
done(text);
});
};
var text = getText(); // you get the expected text
魔术吧?
我不知道this.async()
呼唤的内部工作。我不知道是否有一个库提供该功能,但你可以看到Backbone.LayoutManager使用这个技巧https://github.com/tbranyen/backbone.layoutmanager/blob/master/backbone.layoutmanager.js(搜索this.async)。
此外,Tim Branyen(骨干布局管理员的作者)在他的视频教程(qazxswpoi大约14:00 - 15:00)中简要介绍了它。在视频中,蒂姆说本阿尔曼提出了这个伎俩。看看这个以及http://vimeo.com/32765088
我认为混合异步和同步功能是一个非常巧妙的技巧。
干杯,