这段代码如何使用promises顺序获取url并按顺序加载到html?

时间:2016-01-13 12:41:05

标签: javascript json asynchronous promise es6-promise

我是javascript承诺的新手,我在JavaScript Promises阅读了有关承诺的教程。给定的代码出现在标题"创建序列"。

基本上故事是一个JSON对象,其中chapterUrls数组包含指向各章JSON对象的链接.getJSON(url)发出GET请求,并且成功时返回带有JSON对象的promise,因为它是promiseValue。

故事json:

{
  "heading": "<h1>A story about something</h1>",
  "chapterUrls": [
    "chapter-1.json",
    "chapter-2.json",
    "chapter-3.json",
    "chapter-4.json",
    "chapter-5.json"
  ]
}

章Json:

{
  "chapter": 1,
  "html": "<p>Chapter 1 text: Cras sollicitudin orci ac velit adipiscing, ut faucibus urna auctor. Pellentesque in sem nec sem molestie malesuada. Sed aliquam mi sit amet sollicitudin luctus. Aenean quis tempus sem, in viverra metus. Maecenas sed urna bibendum, cursus lectus sed, ultricies risus.</p>"
}

我无法理解这段代码中发生了什么。这段代码如何按顺序取章按顺序将它们加载到html ?< / p>

    // Start off with a promise that always resolves
var sequence = Promise.resolve();

// Loop through our chapter urls
story.chapterUrls.forEach(function(chapterUrl) {
  // Add these actions to the end of the sequence
  sequence = sequence.then(function() {
    return getJSON(chapterUrl);
  }).then(function(chapter) {
    addHtmlToPage(chapter.html);
  });
});

2 个答案:

答案 0 :(得分:2)

forEach循环有效地构建了一个像这样的链:

Promise.resolve().then(function() {
    return getJSON(story.chapterUrls[0]).then(function(chapter) {
        addHtmlToPage(chapter.html);
    });
}).then(function() {
    return getJSON(story.chapterUrls[1]).then(function(chapter) {
        addHtmlToPage(chapter.html);
    });
}).then(function() {
    return getJSON(story.chapterUrls[2]).then(function(chapter) {
        addHtmlToPage(chapter.html);
    });
}).then(function() {
    // etc.
});

当然,根据story.chapterUrls的长度,会有更多或更少的阶段。

Promise.resolve()作为“种子承诺”时,链条将在建筑阶段完成后立即开始解决(实际上在稍后的事件转弯中尽快)。第一个getJSON()将被调用,当它结算时,第一个addHtmlToPage()及其结算时,第二个getJSON()依此类推(在其自身事件中的每个阶段转向)。

一旦构建,链将一直解决,除非发生错误。应该包含一个错误处理程序来记录/显示错误,否则它将是静默的。

story.chapterUrls.forEach(function(chapterUrl) {
  sequence = sequence.then(function() {
    return getJSON(chapterUrl);
  }).then(function(chapter) {
    addHtmlToPage(chapter.html);
  });
}).catch(function(error) {
  console.log(error);
});

答案 1 :(得分:1)

我自己对Promises的理解有限,但这是我的阅读方式:

根据代码中的注释,从空Promise对象开始。这个承诺将立即解决。

然后,对于每个章节URL,序列继续,首先是getJSON(它本身是一个承诺,它将在获取JSON时解析),然后是一个函数将处理后的JSON添加为HTML到页面 - 因为这个不会返回任何内容,它会立即解析。

这个想法是,因为您将getJSONaddHtmlToPage函数添加到序列中,然后将按顺序解析它们。主要因素是getJSON本身是一个承诺,只有在请求完成时才会解析。通过这种方式,它将按照数组的顺序逐个加载它们。

这与更“传统”的AJAX请求形成对比,在这些请求中,它们可能无法按照发送的顺序完成。在Promise真的是一个“东西”之前,AJAX请求必须是同步的,否则就必须进行巧妙的欺骗(例如,将一个空的<div>作为占位符,AJAX请求将在完成时填写。