Javascript ES 6和谐异步类方法链接

Javascript ES 6和谐异步类方法链接,javascript,async-await,es6-class,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);

这是一个简单的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
有效,但
返回此
无效。 当然,我可以一个接一个地启动这个方法,但我喜欢使用链接

doSomething = async () => {
    await this.doSomethingChained(1);
    await this.doSomethingChained(2);
    await this.doSomethingChained(3);
};
工作起来很有魅力

a is 1
a is 3
a is 6

您可以像下面这样链接您的承诺:

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

您可以像下面这样链接您的承诺:

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

根据以下语法进行链接:

this.doSomethingChained(1).doSomethingChained(2)
。。。根据定义是同步的:JavaScript将同步计算参数和函数调用;你对此无能为力。因此,这种语法不适合异步代码

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

关于你的问题:

我不明白为什么
这个.a
可以工作,但是
返回
这个不行

return此
确实有效,但根据规范,
async
函数中的
return
语句提供的值定义了承诺值,而不是
doSomethingChained
的返回值,因为
async
函数总是(同步)返回承诺

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


请注意,
async
函数在没有
wait
时不是很有用。如果没有它,您也可以使用普通函数。

根据以下语法进行链接:

this.doSomethingChained(1).doSomethingChained(2)
。。。根据定义是同步的:JavaScript将同步计算参数和函数调用;你对此无能为力。因此,这种语法不适合异步代码

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

关于你的问题:

我不明白为什么
这个.a
可以工作,但是
返回
这个不行

return此
确实有效,但根据规范,
async
函数中的
return
语句提供的值定义了承诺值,而不是
doSomethingChained
的返回值,因为
async
函数总是(同步)返回承诺

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


请注意,
async
函数在没有
wait
时不是很有用。如果没有它,您也可以使用普通函数。

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

我想你可以用诺言来连锁承诺

         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);

async将返回一个承诺,对吗?因此,这将在.then(doSomethingChained(2))中。您想要的“链接”是一种暗示同步执行的语法。这与承诺的异步性质不兼容。您需要
等待
然后
。async将返回承诺,对吗?因此,这将在.then(doSomethingChained(2))中。您想要的“链接”是一种暗示同步执行的语法。这与承诺的异步性质不兼容。您需要
等待
然后
。看起来代码比我想写的要多,我想您现在可以链接承诺了。@Nabor使用您的等待,它会创建这样的承诺地狱看起来代码比我想写的要多,我以为你现在可以把承诺串起来了。@Nabor用你的等待来创造这样的承诺地狱