条件为真时,连锁承诺

时间:2018-08-24 23:23:50

标签: javascript promise

我正在尝试使用JS Promise通过XHR获取所有页面。

对我来说,通过递归回调实现这一点相对比较琐碎,但是我如何通过promises实现呢?

没有承诺的简化示例:

class Foo {
    getPages(callback, pagesCount)
    {
        if (typeof(pagesCount) === 'undefined') {
            pagesCount = 0;
        }

        // Let's say its async XHR
        window.setTimeout(() => {
            ++pagesCount;
            // Let's say that in 90% of cases we will get a full page
            if (Math.random() < 0.9) {
                console.log('Page received!');
                this.getPages(callback, pagesCount);
            } else {
                console.log('Last page received!');
                callback(pagesCount);
            }
        }, 1000);
    }

    doStuff(pagesCount)
    {
        console.log('Total pages: ' + pagesCount);
    }

    run()
    {
        this.getPages(this.doStuff);
    }
}

(new Foo()).run();

我正在尝试实现以下目标:

class Foo {
    getPages()
    {
        ...
    }

    doStuff(pagesCount)
    {
        console.log('Total pages: ' + pagesCount);
    }

    run()
    {
        this.getPages().then(this.doStuff);
    }
}

(new Foo()).run();

1 个答案:

答案 0 :(得分:3)

async/await递归承诺出现之前,确实是不可能的。您必须将promise转换为易于回调的代码,然后使用回调进行递归。

但是,async/await允许您执行所需的操作:

async getPages(pagesCount)
{
    if (typeof(pagesCount) === 'undefined') {
        pagesCount = 0;
    }

    // Let's say its async XHR
    while () {

        // Call promisified XHR like this:
        // xhrResult = await XHR();

        // Call callback based XHR like this: 
        // xhrResult = await new Promise(function(ok,err){
        //   XHR(function (error, result) {
        //     if (error) {
        //       err(error)
        //   } else {
        //       ok(result)
        //   }    
        // });

        if (Math.random() < 0.9) {
            console.log('Page received!');
            return await getPages(pagesCount);
        } else {
            console.log('Last page received!');
            return pagesCount;
        }
    };
}

注意:标记为async的所有函数均返回承诺。现在,您可以这样做:

getPages(100).then(count => console.log(count + ' pages left'))