Создание Promises в цикле и прерывание цикла при возникновении некоторых разрешенных условий - PullRequest
0 голосов
/ 28 октября 2018

Я пишу на гусеничном шасси.Задача - отсканировать в худшем случае 10 страниц.Может случиться так, что мне нужно отсканировать только 1 страницу, но это зависит от содержимого страницы.Если на первой странице нет элемента, который я ищу, мы переходим на вторую страницу, пока не достигнем 10 страниц.Нас не интересует страница 11 и более.Итак, у нас есть предел.Я хотел бы вызвать запрос для страницы 1 и, если элемент найден, прервать цикл и решить Promise.

Псевдокод:

func findItem(item: Item): Promise<PageIndex> {
    for (let page=1; page<=10; page++) {
        create url with page as url
        create promise that request url and resolve to content as content
        if content contains item {
            return Promise.resolve(page); // We are interesting in on which page the item is.
            // Here we are breaking loop and exit function because we
            // Found what we were looking for
        }
        // continue to next page because content does not contain item on this page
    }
    // We didnt find item on first 10 pages
    return Promise.resolve(-1)
}

Так что я не знаю, как реализовать это, используяРодные обещания и машинопись.Я знаю, как работают Promises в целом, и я использовал их много раз, но этот вариант использования является новым для меня.Кто-нибудь может помочь?

1 Ответ

0 голосов
/ 28 октября 2018

Вам нужны две функции (может быть, три), одна для запроса страницы (назовем ее точно requestPage(), я не буду показывать, как вы должны реализовать ее, как это должно быть довольно очевидно), и возвращать проанализированный результат (чтоможет быть другой функцией, в зависимости от ваших потребностей в разборе), и оркестратором (цикл, который есть в вашем псевдокоде).

Хитрость в том, что ваш оркестратор должен быть функцией async.

async function findItem(item: Item) {
  for (let page = 1; page <= 10; page++) {
    const contents = await requestPage(page);
    if (contents.include('whateverYouAreInterestedIn')) {
      return page;
    }
  }
  return -1;
}

Обратите внимание, насколько близко это напоминает синхронно выглядящий код.Интересные биты: async, который я добавил перед ключевым словом function, и await, который я добавил перед обещанием, возвращаемым requestPage(page).

Кроме того, в качестве дополнения, TypeScript может, как правило, выводитьвозвращаемый тип функций (даже асинхронные функции), поэтому почти никогда не требуется явно указывать тип возвращаемого значения.


Стоит отметить, что равно возможно реализовать без использования асинхронной функции, с умным использованием цепочки .then() s и полурекурсивной функции, но, на мой взгляд, она гораздо менее читаема, чем простая асинхронная функция с чистым циклом.

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