Разработка быстрого интерфейса Javascript к краткому обзору далеко асинхронная природа Ajax

Как я разработал бы API, чтобы скрыть асинхронную природу Ajax и Запросов HTTP, или в основном задержать его для обеспечения быстрого интерфейса. Показать пример с Твиттера, нового Где угодно 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('

' + status.text + '

'); }); function filterer(status) { return status.text.match(/photography/); }

по сравнению с этим (асинхронная природа каждого вызова явно видима),

T.User.find('ded', function(user) {
    user.timeline(function(statuses) {
        statuses.first(20).filter(filterer).each(function(status) {
            $('div#tweets').append('

' + status.text + '

'); }); }); }); function filterer(status) { return status.text.match(/photography/); }

Это находит пользователя, получает их временную шкалу твита, фильтрует только первые 20 твитов, применяет пользовательский фильтр и в конечном счете использует функцию обратного вызова для обработки каждого твита.

Я предполагаю, что хорошо разработанный API как это должен работать как конструктор запросов (думайте ORMs), где каждый вызов функции создает запрос (URL HTTP в этом случае), пока он не поражает функцию цикличного выполнения, такую как each/map/etc., HTTP-вызов сделан, и переданный в функции становится обратным вызовом.

Маршрут простой разработки должен был бы выполнить каждый синхронный вызов Ajax, но это - вероятно, не лучшее решение. Я интересуюсь выяснением способа сделать это асинхронным, и все еще скрыть асинхронную природу Ajax.

19
задан Anurag 19 May 2010 в 00:53
поделиться

3 ответа

Взгляните на следующую статью, опубликованную всего пару дней назад Дастином Диасом, инженером Twitter на @anywhere:

Он рассказывает о действительно хорошей технике, которая позволяет реализовать свободный интерфейс на асинхронных методах, в основном методах, сцепленных вместе независимо от обратного вызова, используя действительно простую реализацию queue.

20
ответ дан 30 November 2019 в 04:29
поделиться

Вопрос синхронности AJAX, как мне кажется, уже абстрагирован такими библиотеками, как jQuery (т.е. ее ajax call, который позволяет вам указать асинхронную или синхронную работу через свойство async). Синхронный режим, если он выбран, скрывает асинхронную природу реализации.

jQuery также является примером беглого интерфейса и цепочки. Есть и другие библиотеки, которые делают то же самое. Это избавляет вас от необходимости изобретать колесо - вы сразу получаете то, что ищете.

Если это работает как ответ, то вы получите хорошую автоматическую совместимость браузеров по всем этим функциям. На создание таких функций с нуля уходит много времени.

Я вижу, что новый API Anywhere от Twitter отмечает jQuery - возможно, все уже есть, если немного покопаться.

0
ответ дан 30 November 2019 в 04:29
поделиться

Я разрабатываю FutureJS, который изначально был основан на обещаниях Крокфорда (оригинальные слайды). Текущая цель - стать Async Toolbox для JavaScript и устранить беспорядок в цепочках.

Futures.chainify(providers, consumers, context, params)

Очередь асинхронных методов позволяет вам выстраивать цепочки действий над данными, которые могут быть или не быть легко доступны. Так работает апи @Anywhere от Twitter.

Вам может понадобиться модель, которая удаленно получает данные таким образом:

Contacts.all(params).randomize().limit(10).display();
Contacts.one(id, params).display();

Которая может быть реализована следующим образом:

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;
  }
});

Что нужно знать:

  • providers - promisables, которые возвращают данные
  • consumers - функции, которые используют и изменяют данные.
    • первым аргументом должны быть данные
    • при возврате promisable следующий метод в цепочке не будет выполняться, пока обещание не будет выполнено
    • при возврате "буквального объекта" следующий метод в цепочке будет использовать этот объект
    • при возврате undefined (или не возвращая ничего) следующий метод в цепочке будет использовать определенный объект
  • context - apply()d для каждого поставщика и потребителя, таким образом становясь объектом this
  • params - зарезервированным для будущего использования

В качестве альтернативы вы можете использовать синхронную цепочку обратных вызовов - то, что вы могли видеть в других местах как chain(). 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(...)

Я назвал его sequence, а не chain, поскольку в _.js уже есть метод с именем chain, а я хотел бы использовать _.methodName и для своей библиотеки.

Посмотрите и дайте мне знать, что вы думаете.

FuturesJS будет работать вместе с jQuery, Dojo и т.д. без проблем. Нет никаких зависимостей. Он будет работать с Node.js (и Rhino при использовании env.js).

=8^D

P.S. Что касается исправления ORM / MVC - вы можете проверить JavaScriptMVC и SproutCore. Я также работаю над собственным решением под названием TriforceJS, но у меня пока ничего не готово к выпуску.

P.P.S Пример 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);
5
ответ дан 30 November 2019 в 04:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: