Цепные обещания пока условие верно - PullRequest
0 голосов
/ 25 августа 2018

Я пытаюсь пересчитать все страницы через XHR, используя JS Promise.

Для меня это относительно тривиально получить это с помощью рекурсивных обратных вызовов, но как я могу добиться этого с помощью обещаний?

Упрощенный пример без обещаний:

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 голосов
/ 25 августа 2018

До появления async/await рекурсивные обещания действительно были невозможны. Вам нужно было бы преобразовать обещание в дружественный к обратному вызову код и выполнить рекурсию с помощью обратных вызовов.

Однако 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'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...