многократная последовательная выборка () Promise

Я должен сделать последовательностьfetch() Обещание: у меня есть только 1 URL за один раз, это означает, что только 1fetch() Обещаю. Каждый раз, когда я получаю JSON, этот содержит URL для другого JSON, поэтому я должен сделать еще одинfetch() Обещаю.

Я могу работать с несколькими обещаниями, но в этом случае я не могу сделатьPromise.all()потому что у меня есть не весь URL, а только один.

Этот пример не работает, все зависает.

function fetchNextJson(json_url) 
{
    return fetch(json_url, {
            method: 'get'
        })
        .then(function(response) {
            return response.json();
        })
        .then(function(json) {
            console.log(json);
            return json;
        })
        .catch(function(err) {
            console.log('error: ' + error);
        });
}


function getItems(next_json_url) 
{
    if (!(next_json_url)) return;

    get_items = fetchNextJson(next_json_url);

    interval = $q.when(get_items).then(function(response) {
        console.log(response);
        next_json_url = response.Pagination.NextPage.Href;
    });

    getItems(next_json_url);
}


var next_json_url = 'http://localhost:3000/one';

getItems(next_json_url);
 FrancescoN26 июн. 2016 г., 04:21
мне нужно скачивать по 1 json за раз: у первого есть ссылка на следующий, и так далее @ guest27131 столько, сколько я хочу .. 1-40. Я остановлюсь, когда в текущем json больше не будет ссылки на следующий json
 charlietfl26 июн. 2016 г., 04:35
Так что, если это для автономной навигации с использованием отдельных ключей хранения, почему вы не можете просто сохранить каждый ответ, как он получен? До сих пор не совсем выяснили, какой конкретно контрольно-пропускной пункт
 charlietfl26 июн. 2016 г., 04:45
ОК ... значит, ничего критического не должно произойти только послевсе результаты получены. Делает это намного проще
 Zohaib Ijaz26 июн. 2016 г., 04:12
каков базовый вариант? когда вы прекратите получать данные?
 FrancescoN26 июн. 2016 г., 04:27
Когда я получаю JSON, я должен сохранить его в местном хранилище, да что-то должно произойти.
 FrancescoN26 июн. 2016 г., 04:33
Индивидуальный ключ, но это не проблема, автономная навигация, 15 КБ для JSON. Пожалуйста, это важно, знаете ли вы, как достичь цели?
 guest27131426 июн. 2016 г., 04:12
Сколько всего запросов ожидается обработать?$q.when() не кажется необходимым. Зачем звонишьgetItems(next_json_url) вне.then() вgetItems() вызов?
 FrancescoN26 июн. 2016 г., 15:37
внутри обещания произошла ошибка. Я думал об этом все, потому что, если обещание не выполняется, вся цепочка перестает работать, если я прав. Итак, что это за карта? У вас есть ссылка на документ / учебник? Спасибо-спасибо
 FrancescoN26 июн. 2016 г., 04:43
Пользователь будет загружать и хранить страницы для просмотра в автономном режиме: каждая страница представляет собой JSON в сочетании с Angular.
 charlietfl26 июн. 2016 г., 04:12
Каково ожидаемое поведение и общая цель?
 charlietfl26 июн. 2016 г., 04:28
Сохранить как один локальный ключ для всех данных или отдельные ключи для каждого ответа? И как это влияет на остальную часть приложения?
 charlietfl26 июн. 2016 г., 05:44
Возможно, стоит убедиться, что у вас есть главная навигационная карта, и вместо этого вы работаете с ней. Было бы легче обрабатывать ошибки, так как одна ошибка разорвет вашу цепочку, а карта даст вам место для отслеживания обновлений с
 charlietfl26 июн. 2016 г., 04:24
Но должно ли что-то происходить только после получения всех данных? Или вы можете сделать так, как делает $ resource, и вернуть пустой массив, который продолжает заполняться во время выполнения запросов? Не понятно, что вы делаете со всеми результатами этих запросов

Ответы на вопрос(1)

Решение Вопроса

Вы можете использовать рекурсию

function fetchNextJson(json_url) {
    return fetch(json_url, {
            method: 'get'
        })
        .then(function(response) {
            return response.json();
        })
        .then(function(json) {
            results.push(json);
            return json.Pagination.NextPage.Href 
                   ? fetchNextJson(json.Pagination.NextPage.Href)
                   : results
        })
        .catch(function(err) {
            console.log('error: ' + error);
        });
}


var next_json_url = 'http://localhost:3000/one';
var results = [];

fetchNextJson(json_url).then(function(res) {
  console.log(res)
})
 charlietfl26 июн. 2016 г., 05:09
Мне понадобилось несколько минут, чтобы обдумать, почему это так хорошо работает ... вывод постоянно пополняетсяthen() цепочки, пока, наконец, не обещание не возвращается. Звучит правильно?
 charlietfl26 июн. 2016 г., 05:23
Сложная часть, я думаю, это как вернуться назад, чтобы заполнить дыры, которые попали в ловушкуfetchNextJson()
 charlietfl26 июн. 2016 г., 05:39
О, я согласен. Просто немного подумав из коробки.
 charlietfl26 июн. 2016 г., 05:54
Должен любить веб-разработчика ... никогда не хватает вещей, чтобы учиться
 guest27131426 июн. 2016 г., 05:11
@charlietfl Да. Еслиjson.Pagination.NextPage.Href определяется, звонитеfetchNextJsonиначе вернусьresults массив
 FrancescoN26 июн. 2016 г., 16:20
ребята, спасибо вам всем: это было невозможно для меня. Это счастье StackOverflow существует, и все, что вы ответили мне. Просто чтобы возобновить обработку ошибок: давайте предположим, что я хочу получить определенную ссылку до 3 раз, в случае ошибки. Что если я получу ошибку внутри.catch()? @ guest271314 вы рассказали об использовании.then(), где начинается очередная повторная загрузка, и.catch()где он кричит об ошибке, внутри первого.catch() если я понял Это правильно? можешь привести пример?
 charlietfl26 июн. 2016 г., 05:36
Еще один сценарий не может быть определен, по-видимому, существует более одной страницы, которая не имеет следующего URL-адреса ... поэтому сначала нужно также прервать рекурсию. Конечно, кажется, что OP лучше иметь главную навигационную карту
 guest27131426 июн. 2016 г., 05:24
@charlietfl.catch() следует прекратить рекурсию, еслиfetchNextJson называется внутри.catch(), Одним из подходов может быть обработка ошибки, а затем возвратfetchNextJson в.then() прикован к.catch() или в.catch(); хотя данное настоящее требование заключается в следующемfetchNextJson с результатами из текущегоfetchNextJson Похоже, что дальнейшие задачи не выполняются, если URL не предоставлен из необязательного источника.
 charlietfl26 июн. 2016 г., 05:33
Да ... я думаю, что создание всей этой резервной стратегии потребовало бы некоторого возрождения
 charlietfl26 июн. 2016 г., 05:12
Сделано упрощенное демо с использованием счетчика вместо нового URL для возвратаplnkr.co/edit/5boVimpYnoE1o41FXZGG?p=preview
 guest27131426 июн. 2016 г., 05:19
@charlietfl«заключение постоянно добавляет then () в цепочку, пока, наконец, не будет возвращено не обещание». Любой результат возвращается из.then() прикован кfetchNextJson должно быть обещано после первого звонка;.then() либо рекурсивно вызываетfetchNextJson или возвращает накопленные результаты или другое значение в качестве значения обещания
 guest27131426 июн. 2016 г., 05:45
 charlietfl26 июн. 2016 г., 05:28
Правильно ... но в случае, скажем, прерывистого соединения во время одного неудачного запроса, можно попытаться вернутьсяfetchNextJson() по крайней мере, один раз для этого конкретного URL. Попытка обернуть голову вокруг этой стратегии еще больше. Или установите таймер, чтобы повторить попытку через минуту
 guest27131426 июн. 2016 г., 05:38
@charlietfl«предположительно, существует более одной страницы, у которой нет следующего URL-адреса ... поэтому сначала нужно также прервать рекурсию» Да, это, кажется, ожидаемый результат; возможно, только результаты с учетом указаний по представлению требований от ОП«Я остановлюсь, когда больше нет ссылки» в ответ на"Сколько всего запросов будет обработано?"
 guest27131426 июн. 2016 г., 16:44
@FrancescoN Смотритеplnkr.co/edit/wkzEbNZ98m3zbSXMfFX1?p=info , ЗаметкаПочему fetch () работает таким образом? «PerMDNAPI fetch () отклоняет обещание только в том случае, если «обнаружена сетевая ошибка, хотя обычно это означает проблемы с правами доступа или подобные». По сути, fetch () отклоняет обещание только в том случае, если пользователь находится в автономном режиме или возникает какая-то маловероятная ошибка сети, такая ошибка поиска DNS. "
 guest27131426 июн. 2016 г., 05:32
Не рассматривал такой случай. Да, мог позвонитьfetchNextJson() с текущим URL в пределах.catch() если произошла ошибка, попытаться продолжить рекурсивную цепочку; хранить, ограничивать количество людей. Хотя, опять же, учитывая данное требование, не будет источника для следующего URL. Если требование включает в себя отдельный массив URL-адресов, можно выполнить итерацию всего массива, независимо от того, были ли обнаружены ошибки, обработаны или возвращен успешный ответ. Однажды ошибка обработана.catch()Могу вернуть обещание прикованным.then() это не должно быть ошибкой внутри.then(); можно продолжить с рекурсивным вызовом функции

Ваш ответ на вопрос