多个顺序的 fetch() 承诺

Posted

技术标签:

【中文标题】多个顺序的 fetch() 承诺【英文标题】:multiple, sequential fetch() Promise 【发布时间】:2016-10-28 07:45:35 【问题描述】:

我必须创建一系列fetch() Promise:我一次只有一个 url,这意味着只有 1 个fetch() promise。每次我收到一个json,这个包含另一个json的url,所以我必须再做一个fetch()promise。

我可以处理多个 promise,但在这种情况下我不能做 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);

【问题讨论】:

预期行为和总体目标是什么? 预计将处理多少个请求? $q.when() 似乎没有必要。为什么在getItems() 通话中在.then() 之外拨打getItems(next_json_url) 基本情况是什么?什么时候停止获取数据? 我必须一次下载 1 个 json:第一个有下一个的参考,依此类推@guest27131,我想要多少就多少.. 1-40。当当前 json 中没有更多参考时,我将停止下一个 json 可能会考虑确保您有一个主导航地图并使用它来工作。会更容易处理错误,因为一个错误会破坏您的链条,而地图将为您提供一个跟踪更新的地方 【参考方案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)
)

【讨论】:

使用计数器而不是使用新的 url 来返回 plnkr.co/edit/5boVimpYnoE1o41FXZGG?p=preview 进行简化演示 @charlietfl "结论是不断地将 then() 添加到链中,直到最终返回一个非承诺。" 从链接到 fetchNextJson.then() 返回的任何结果都应该是第一次通话后承诺; .then() 要么递归调用 fetchNextJson 要么返回累积结果或其他值,作为承诺值 @charlietfl .catch() 应该停止递归,除非在.catch() 中调用了fetchNextJson。一种方法是处理错误,然后在链接到.catch().catch().then() 处返回fetchNextJson;尽管目前的要求是使用当前fetchNextJson 的结果调用下一个fetchNextJson,但似乎没有任何进一步的任务要执行-除非从可选来源提供了url 没有考虑过这种情况。是的,如果发生错误,可以使用.catch() 内的当前url 调用fetchNextJson(),以尝试继续递归链;存储,限制重试次数。不过,再一次,鉴于目前的要求,不会有下一个 url 的来源。如果要求包括单独的 url 数组,则可以迭代整个数组,无论是捕获、处理错误还是返回成功的响应。一旦.catch()处理了错误,可以返回promise到链式.then(),这不应该是.then()中的错误;可以继续递归调用函数 哦,我同意。只是跳出框框思考一下。

以上是关于多个顺序的 fetch() 承诺的主要内容,如果未能解决你的问题,请参考以下文章

fetch:拒绝带有 JSON 错误对象的承诺

React Native Fetch:第二个承诺挂起

承诺按顺序运行嵌套承诺并在第一次拒绝时解决

如何在 Fetch 的承诺链之外获取响应数据? [复制]

.catch() 甚至通过 fetch() 从另一个承诺中捕获所有错误

使用 fetch 和 ES6 承诺处理自定义错误的最简洁方法