前言
最近项目开发的时候遇到了一个问题 -- 如何链式调用 async?
(当然不是指的 promise.then().then()
, 这种的
举个例子
class A {
val = 1
async foo() {
this.val += 1
return this
}
async bar(x) {
this.val += x
return this
}
}
const a = new A()
// 一般我们会这么去写
const v = await a.foo().then(
a => a.foo()
).then(
a => a.bar(10)
).then(
a => a.val
)
// 或者这么写
const v = (await (
await a.foo()
).bar(10)).val
// 上面俩种写法感觉都不是很好看,我的目的是想如此去用 stream(chain) 的风格去编写代码
const v = await a
.foo()
.bar(10)
.val
想法
在询问了一位大佬后,看他的源码写了一下
(因为他的那部分代码在处理类的 property 上有一些问题,所以后面放弃了他的库
库用到了下面一些技术(其实还有 ts
- Proxy
- Promise
实现
我们可以从第一种写法中得到启发,只要 hack 掉每次的 async method 的返回值,与 Promise 的调用即可
代码花了一半去生成类型,如果对 ts 不感冒,可以直接看下面部分
使用
npm install stream-async
# or
yarn add stream-async
- 简单的 class 示范
import { streamAsync } from 'stream-async'
class A {
foo = 1
async asyncFun() {
this.foo += 1
return this
}
}
const a = streamAsync(new A())
a.asyncFun().asyncFun()
console.log(a.foo)
// there will output `3`
- 稍微有设计感点的写法
import { streamAsync } from 'stream-async'
class A {
stream = streamAsync(this)
foo = 1
fun () {
this.foo += 1
return this
}
async asyncFun() {
this.foo += 1
return this
}
async asyncFun0(x) {
this.foo += x
return this
}
}
const a = new A()
a.stream
.asyncFun()
.fun()
.asyncFun()
.asyncFun0(10)
console.log(a.foo)
// there will output `14`
相关链接
感谢
- shigma 的帮助, 没有这个仓库,我估计是比较难写的 prochain