ES6类异步方法链式调用报错问题求助
你遇到的问题核心在于async函数的返回值特性:所有async函数都会自动将返回值包装成一个Promise对象——哪怕你写了return this,实际返回的也是Promise.resolve(this),而不是直接的Test实例。
当你尝试链式调用await this.doSomethingChained(1).doSomethingChained(2)时,this.doSomethingChained(1)返回的是一个Promise,你紧接着在这个Promise上调用doSomethingChained方法,但Promise原型上根本没有这个方法,所以自然会抛出TypeError。
而你单独用await调用每个方法时,await会等待Promise完成并解析出实际的返回值(也就是你的Test实例),此时你只是依次调用实例上的方法,this指向正确,所以this.a能正常更新,代码也能正常运行。
如果你想实现类似同步方法的链式调用体验,有两种实用思路:
思路1:利用Promise链的then方法
因为每个doSomethingChained返回的Promise最终会resolve到实例本身,所以可以通过then来链式调用:
class Test { constructor() { this.a = 0; this.b = 1; } doSomething = async () => { await this.doSomethingChained(1) .then(self => self.doSomethingChained(2)) .then(self => self.doSomethingChained(3)); }; doSomethingChained = async (x) => { this.a = this.a + x; console.log('a is', this.a); return this; }; }
这里then的回调参数就是解析后的实例,所以可以继续调用方法,实现链式效果。
思路2:用await逐个解开Promise(你已验证的写法)
这种写法虽然看起来不是“链式”的语法,但本质上是按顺序执行异步操作,逻辑清晰且不易出错,也是异步场景下的常用写法:
doSomething = async () => { await this.doSomethingChained(1); await this.doSomethingChained(2); await this.doSomethingChained(3); };
额外说明:箭头函数类方法的this绑定
你代码里的this.a能正常工作,是因为你用了箭头函数作为类实例方法——这种写法会自动将方法的this绑定到类实例上,避免了普通函数方法中可能出现的this指向丢失问题,这部分是完全没问题的。
内容的提问来源于stack exchange,提问作者Nabor

