Javascript 这段代码如何使用承诺来顺序获取URL并将其顺序加载到html?

Javascript 这段代码如何使用承诺来顺序获取URL并将其顺序加载到html?,javascript,json,asynchronous,promise,es6-promise,Javascript,Json,Asynchronous,Promise,Es6 Promise,我不熟悉javascript承诺,我在上阅读了一篇关于承诺的教程。给定的代码出现在“创建序列”标题下 基本上,story是一个JSON对象,它具有ChapterURL数组,其中包含指向各个chapter JSON对象的链接。getJSON(url)发出GET请求,并在成功时返回一个带有JSON对象作为promiseValue的承诺 故事json: { "heading": "<h1>A story about something</h1>", "chapterUr

我不熟悉javascript承诺,我在上阅读了一篇关于承诺的教程。给定的代码出现在“创建序列”标题下

基本上,story是一个JSON对象,它具有ChapterURL数组,其中包含指向各个chapter JSON对象的链接。getJSON(url)发出GET请求,并在成功时返回一个带有JSON对象作为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"
  ]
}

我自己对承诺的理解有限,但我是这样理解的:

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

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

这个想法是,由于您正在向序列中添加
getJSON
addHtmlToPage
函数,因此它们将按顺序解析。主要因素是
getJSON
one本身就是一个承诺,只有在请求完成时才能解析。这样,它将按照数组的顺序逐个加载它们


这与更“传统”的AJAX请求形成对比,在AJAX请求中,它们可能不会按照发送的顺序完成。在承诺真正成为“东西”之前,AJAX请求必须是同步的,否则就必须进行巧妙的欺骗(例如,将一个空的
作为占位符,AJAX请求完成后将填充该占位符)。forEach循环有效地构建了这样一个then链:

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.
});
当然,根据故事的长度,会有或多或少的阶段

使用
Promise.resolve()
作为“种子承诺”,链将在构建阶段一完成就开始结算(实际上是在稍后的事件回合中尽快结算)。第一个
getJSON()
将被调用,当它解析时,第一个
addHtmlPage()
将被调用,当它解析时,第二个
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);
});

因此,在第一次运行时,序列已经解析,因此它执行.then()来获取第一个url。但是,在第二次运行时,仅当上一次提取成功时,才会执行.then(),因为序列已分配给上一次调用的结果。基本上,我在这个语句中循环执行如下操作:
sequence.then(function(){return getJSON(chapterUrl[0]);})。然后(function(chapter){addHtmlToPage(chapter.html);})。然后(function(){return getJSON(chapterUrl[1])。然后(function(chapter){addHtmlToPage(chapter.html)///code>我说得对吗?
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.forEach(function(chapterUrl) {
  sequence = sequence.then(function() {
    return getJSON(chapterUrl);
  }).then(function(chapter) {
    addHtmlToPage(chapter.html);
  });
}).catch(function(error) {
  console.log(error);
});