ES 6 Harmony - объединение асинхронных методов класса - PullRequest
0 голосов
/ 17 мая 2018

Это простой пример JavaScript:

class Test {
    constructor() {
        this.a = 0;
        this.b = 1;
    }

    doSomething = async () => {
        await this.doSomethingChained(1)
            .doSomethingChained(2)
            .doSomethingChained(3);
    };

    doSomethingChained = async (x) => {
        this.a = this.a + x;
        console.log('a is', this.a);
        return this;
    };
}

Затем он запускается с использованием метода тестирования, но это не имеет значения

test('Vorgang erfassen', async t => {

    const t1 = new Test();
    await t1.doSomething();

Консоль содержит следующее:

a is 1
TypeError: _this2.doSomethingChained(...).doSomethingChained is not a function

Я не понимаю, почему this.a работает, а return this нет.Конечно, я могу запустить метод один за другим, но я бы хотел использовать цепочку.

doSomething = async () => {
    await this.doSomethingChained(1);
    await this.doSomethingChained(2);
    await this.doSomethingChained(3);
};

Работает как шарм.

a is 1
a is 3
a is 6

Ответы [ 3 ]

0 голосов
/ 17 мая 2018

Цепочка в соответствии с этим синтаксисом:

this.doSomethingChained(1).doSomethingChained(2)

... по определению является синхронной: JavaScript будет оценивать аргументы и вызовы функции синхронно;с этим ничего не поделаешь.Так что этот синтаксис просто не подходит для асинхронного кода.

Асинхронный код по своей природе опирается на обратные вызовы.Даже обещания включают асинхронное выполнение обратных вызовов.С await это менее заметно, но, тем не менее, контекст выполнения соответствующей функции async восстанавливается асинхронно, продолжая выполнение после разрешения await.

К вашему вопросу:

Я не понимаю, почему this.a работает, но return это не так.

return this работает , но по спецификации значение, предоставляемое с оператором return в функции async, определяет обещанное значение ,не return значение doSomethingChained, поскольку async функция всегда возвращает обещание (синхронно).

Итак, в вашем коде (синхронно!) Возвращаемое значение doSomethingChained является обещанием, а не this.Это объясняет, почему вы получаете ошибку.

Обратите внимание, что функция async не очень полезна, когда она не имеет await.Без него вы могли бы также использовать обычную функцию.

0 голосов
/ 23 июня 2019

Я думаю, что вы можете просто связать обещания, используя Promise.all

         class Laundry {

          constructor() {
            this.queue = [];
            this.clothes = [];
          }


          addClothes(cloth) {
            this.clothes.push(cloth);

            return this;
          }


          removeClothes(cloth) {
            const clothIndex = this.clothes.findIndex(value => value === cloth);
            this.clothes.splice(clothIndex, 1);

            return this;
          }


          wash() {
            this.clothes = 'washed';

            const item = new Promise(resolve => setTimeout(() => resolve(1), 3000)).catch()

            this.queue.push(item);

            return this;
          }


          rinse() {
            this.clothes = 'rinsed';

            const item = new Promise(resolve => setTimeout(() => resolve(2), 2000)).catch()

            this.queue.push(item);

            return this;
          }


          finish() {
            return Promise.all(this.queue);
          }
        }


        module.exports = Laundry;

, а затем звонить вот так ...

const Laundry = require('./laundry');

const laundry = new Laundry();

// class chain methods...
laundry.wash().rinse().finish().then(console.log).catch(console.error);
0 голосов
/ 17 мая 2018

Вы можете связать свои обещания, как показано ниже:

doSomething = async () => {
    await this.doSomethingChained(1)
       .then(() => this.doSomethingChained(2))
       .then(() => this.doSomethingChained(3));
};
...