Anu*_*rag 19 javascript ajax asynchronous fluent-interface
我如何设计一个API来隐藏AJAX和HTTP请求的异步性质,或者基本上将其延迟以提供流畅的界面.要在Twitter的新Anywhere API中显示示例:
// get @ded's first 20 statuses, filter only the tweets that
// mention photography, and render each into an HTML element
T.User.find('ded').timeline().first(20).filter(filterer).each(function(status) {
$('div#tweets').append('<p>' + status.text + '</p>');
});
function filterer(status) {
return status.text.match(/photography/);
}
Run Code Online (Sandbox Code Playgroud)
vs this(每个调用的异步性质清晰可见)
T.User.find('ded', function(user) {
user.timeline(function(statuses) {
statuses.first(20).filter(filterer).each(function(status) {
$('div#tweets').append('<p>' + status.text + '</p>');
});
});
});
function filterer(status) {
return status.text.match(/photography/);
}
Run Code Online (Sandbox Code Playgroud)
它找到用户,获取他们的推文时间轴,仅过滤前20条推文,应用自定义过滤器,并最终使用回调函数来处理每条推文.
我猜这样设计良好的API应该像查询构建器(想想ORM)一样工作,每个函数调用构建查询(在这种情况下为HTTP URL),直到它遇到循环函数,如每个/ map /等.进行HTTP调用,传入函数成为回调函数.
一个简单的开发途径是使每个AJAX调用同步,但这可能不是最好的解决方案.我有兴趣找出使其异步的方法,并仍然隐藏AJAX的异步性质.
CMS*_*CMS 20
看看几天前由@anywhere的Twitter工程师Dustin Diaz发表的以下文章:
他谈到了一个非常好的技术,它允许你在异步方法上实现一个流畅的接口,基本上是独立于回调链接在一起的方法,使用一个非常简单的Queue实现.
我正在开发FutureJS,它最初是基于Crockford的承诺(原始幻灯片).目前的目标是成为JavaScript的异步工具箱并消除链接杂乱.
异步方法排队允许您对可能或可能不可用的数据进行链接操作.这就是Twitter的@Anywhere api的工作原理.
您可能需要一个以这种方式远程获取数据的模型:
Contacts.all(params).randomize().limit(10).display();
Contacts.one(id, params).display();
Run Code Online (Sandbox Code Playgroud)
哪个可以像这样实现:
var Contacts = Futures.chainify({
// Providers must be promisables
all: function(params) {
var p = Futures.promise();
$.ajaxSetup({ error: p.smash });
$.getJSON('http://graph.facebook.com/me/friends', params, p.fulfill);
$.ajaxSetup({ error: undefined });
return p.passable();
},
one: function(id, params) {
var p = Futures.promise();
$.ajaxSetup({ error: p.smash });
$.getJSON('http://graph.facebook.com/' + id, params, p.fulfill);
$.ajaxSetup({ error: undefined });
return p.passable();
}
},{
// Consumers will be called in synchronous order
// with the `lastResult` of the previous provider or consumer.
// They should return either lastResult or a promise
randomize: function(data, params) {
data.sort(function(){ return Math.round(Math.random())-0.5); // Underscore.js
return Futures.promise(data); // Promise rename to `immediate`
},
limit: function(data, n, params) {
data = data.first(n);
return Futures.promise(data);
},
display: function(data, params) {
$('#friend-area').render(directive, data); // jQuery+PURE
// always return the data, even if you don't modify it!
// otherwise your results could be unexpected
return data;
}
});
Run Code Online (Sandbox Code Playgroud)
要知道的事情:
providers - 返回数据的promisablesconsumers - 使用和/或改变数据的功能
dataundefined(或不返回任何东西)时,链中的下一个方法将使用定义的对象context- apply()d为每个提供者和消费者,从而成为this对象params - 留作将来使用或者,您可以使用同步回调链接 - 您可能在其他地方看到的链接().next()或then():
Futures.sequence(function(callback) {
$.getJSON("http://example.com", {}, callback);
}).then(function(callback, result, i, arr) {
var data = transform_result(result);
$.getJSON("http://example.com", data, callback);
}).then(...)
Run Code Online (Sandbox Code Playgroud)
我命名它sequence而不是chain因为_.js已经有一个名为的方法chain,我也想在我的库中使用_.methodName.
FuturesJS将与jQuery,Dojo等一起工作,没有问题.没有依赖关系.它将与Node.js(以及使用env.js时的Rhino)一起使用.
= 8 ^ d
PS对于ORM/MVC修复 - 您可以查看JavaScriptMVC和SproutCore.我也正在开发一个名为TriforceJS的自己的解决方案,但我还没有准备好发布任何东西.
PPS示例 promisables
var doStuff = function (httpResult) {
// do stuff
},
doMoreStuff = function (httpResult) {
// do more stuff
};
function fetchRemoteData(params) {
var promise = Futures.promise();
$.getJSON("www.example.com", params, promise.fulfill, 'jsonp');
return promise;
}
p = fetchRemoteData(params);
p.when(doStuff);
p.when(doMoreStuff);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5813 次 |
| 最近记录: |