ES 6 Harmony异步类方法链接

时间:2018-05-17 10:50:53

标签: javascript async-await es6-class

这是一个简单的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 :(得分:2)

你可以如下链接你的承诺:

let outcome = document.querySelector('[class^="outcome"]')
outcome.className = outcome.className.replace(/\boutcome--active.+?/g, '');

答案 1 :(得分:1)

根据这种语法链接:

this.doSomethingChained(1).doSomethingChained(2)

...按定义同步:JavaScript将同步评估参数和函数调用;你无能为力。所以这种语法不适合异步代码。

异步代码本质上依赖于回调。甚至承诺涉及回调的异步执行。使用await这不太明显,但是,相应的async函数的执行上下文异步恢复,在await解析后继续执行。

问题:

  

我不明白为什么this.a有效,但return没有。

return this 工作,但根据规范,return函数中async语句提供的值定义承诺的值,而不是doSomethingChained return 值,因为async函数总是返回一个promise(同步)。

因此,在您的代码中,doSomethingChained的(同步!)返回值是一个承诺,而不是this。这就解释了为什么会出现错误。

请注意,async函数没有await时效果不大。没有它你也可以使用正常的功能。

答案 2 :(得分:0)

我认为您可以通过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);