Элегантный способ запустить много асинхронных «вещей» в пакетах в цикле, когда общее количество не известно, пока не вернется первая «вещь»? - PullRequest
0 голосов
/ 08 января 2012

Я работаю над проблемой вызова API Stack Exchange (1.1) на всех страницах (вопросы, теги и т. Д.). Но на самом деле кажется, что это может быть и общая проблема, поэтому я публикую здесь, а не в StackApps.

Таким образом, простой способ - это сделать предварительный вызов, просто чтобы получить сумму, а затем поместить остаток в цикл.

Но этот первый вызов может фактически извлечь первую страницу результатов и сохранить один вызов.

Но выполнение этого первого вызова в особом случае, по-видимому, усложняет код гораздо больше, чем описанный выше «простой способ».

Это усложняется тем, что я могу получить несколько страниц одновременно, но не все из-за ограничений по скорости.

Я буду использовать JavaScript с jQuery, если они предоставят что-нибудь полезное.

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

batch_num = 0
batch_size = 1 // how many pages to fetch in each batch. 1st is just 1 so we know the total

forever {
  get_batch (batch_size)

  if (batch_num == 0) {
    calculate batch_num to use from now on based on the total number of pages and the rate limits
  }

  if (batch_num == last) {
    break
  }

  ++ batch_num
}

exit

function get_batch (batch_size) {
  for (i = 0; i < batch_size; ++i) {
    getJSON next page
  }
}

Код слишком упрощен, потому что то, что происходит в асинхронных обратных вызовах, важно и делает код более сложным и трудным для чтения.

Я пробовал как итеративный, так и рекурсивный подходы, но не могу разобраться в деталях, чтобы понять это правильно.

Итак, является ли «легкий путь» лучшим способом, несмотря на необходимость дополнительного асинхронного вызова? Или действительно есть способ получить что-то вроде моего псевдокода, работающего элегантно, а не запутанно?

(Если вы считаете, что это слишком специализировано и не относится к SE API, я рад перенести его в StackApps.)

Ответы [ 2 ]

1 голос
/ 18 февраля 2013

Через некоторое время после постановки этого вопроса я попал в node.js, где работа с асинхронным кодом, возможно, даже более важна, чем в JavaScript браузера.

Один из самых популярных модулей / библиотек для создания асинхронного потока управленияитерации для контейнеров просты: Async.js от "caolan" .

Включает три функции с поддержкой пакетной обработки:

limit - максимумколичество итераторов / задач для запуска в любое время.

1 голос
/ 08 января 2012

Я бы сказал, что в 99% случаев вы должны пойти по легкому пути.

Учтите, что если вы получите счет 100, вы будете делать 101 вызов вместо 100, что не стоит усложнения кода, о котором вы, вероятно, пожалеете, если вам потребуется изменить логику позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...