Callback and Promise

Promise

这个没有什么好讲的。看看文档,玩玩例子。 Promise MDN

Callback to promise

这个就需要Promise的构造函数了。 请细细查看,run sample code。 下面例子是把XMLHttpRequest转成Promise

        function get(url) {
            return new Promise(
                (resolve, reject) => {
                    try {
                        var xmlHttp = new XMLHttpRequest();
                        xmlHttp.open('GET', url);
                        xmlHttp.onload = (ev) => {
                            resolve(xmlHttp.response);
                        }
                        xmlHttp.onerror = (err) => {
                            reject(Error("Network Error"));
                        }
                        xmlHttp.send();
                    } catch (err) {
                        console.log("err " + err);
                        reject(err)
                    }
                });
        }

Sequencing and Paralleliism

Sequencing

这个很简单,只需要在一个Prmoisethen里面return一个新的Prmoise就可以。

          getJson(jsonHost + 'story.json').then(result => {
            addHtmlToPage(result.heading);
            return getJson(jsonHost + result.chapterUrls[0]);
           // document.querySelector('.spinner').style.display = 'none';
        }).then(
            (chapter) => {
                addHtmlToPage(chapter.html);
            }
        );

如果需要利用循环来chain多个Promise,这里面有个小坑。详情请参见promise_sequencing.html.

Sample code 如下:

      //需要用一个promise 把所有promise 用 then 串联起来,要不然就是并发。
        var sequence = Promise.resolve();
        getJson(jsonHost + 'story.json').then(
            story =>{
                addHtmlToPage(story.heading);
                story.chapterUrls.forEach(chapterUrl => {
                    sequence = sequence.then(
                        value =>{
                            return getJson(jsonHost + chapterUrl).then(
                                chapter =>{
                                    addHtmlToPage(chapter.html);
                                }
                            );
                        }
                    )
                });
            }
        )

当然这完全可以用 Array.prototype.reduce(), 达到一样效果。

            getJson(jsonHost + 'story.json').then(
            story => {
                addHtmlToPage(story.heading);
                story.chapterUrls.reduce(
                    (previous, current) => {
                        return previous.then(
                            () => { return getJson(jsonHost + current); }
                        ).then(
                            chapter => {
                                addHtmlToPage(chapter.html);
                            });
                    }, Promise.resolve()
                )
            }
        )

Parallel

好了开始并行吧,要不然Promise有什么意义呢?

Send them all, and control order

Send them all, and when all are done->process

类比小说 load, load 完成后,一起显示

Send them all and when anyone resolve->process

类比小说 load, 先回来的章节,就显示