Skip to content

Commit

Permalink
Added support for async iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
mweststrate committed Mar 12, 2018
1 parent 5ab68b1 commit cbfbbca
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -19,6 +19,7 @@ The changes mentioned here are discussed in detail in the [release highlights](h
* `toJS` now accepts the options: `{ detectCycles?: boolean, exportMapsAsObjects?: boolean }`, both `true` by default
* Introduced `flow` to create a chain of async actions. This is the same function as [`asyncActions`](https://github.com/mobxjs/mobx-utils#asyncaction) of the mobx-utils package
* These `flow`'s are now cancellable, by calling `.cancel()` on the returned promise, which will throw a cancellation exception into the generator function.
* `flow` also has experimental support for async iterators (`async * function`)
* The flow typings have been updated. Since this is a manual effort, there can be mistakes, so feel free to PR!

* `computed(fn, options?)` / `@computed(options) get fn()` now accept the following options:
Expand Down
5 changes: 5 additions & 0 deletions src/api/flow.ts
Expand Up @@ -154,6 +154,11 @@ export function createFlowGenerator(name: string, generator: Function) {
}

function next(ret: any) {
if (ret && typeof ret.then === "function") {
// an async iterator
ret.then(next, reject)
return
}
if (ret.done) return resolve(ret.value)
pendingPromise = Promise.resolve(ret.value) as any
return pendingPromise!.then(onFulfilled, onRejected)
Expand Down
56 changes: 56 additions & 0 deletions test/base/typescript-tests.ts
Expand Up @@ -1579,3 +1579,59 @@ test("it should support asyncAction as decorator (babel)", async () => {

expect(await x.f(3)).toBe(16)
})

test("flow support async generators", async () => {
;(Symbol as any).asyncIterator =
(Symbol as any).asyncIterator || Symbol.for("Symbol.asyncIterator")

async function* someNumbers() {
await Promise.resolve()
yield 1
await Promise.resolve()
yield 2
await Promise.resolve()
yield 3
}

let steps = 0
const start = mobx.flow(async function*() {
let total = 0
for await (const number of someNumbers()) {
total += number
}
return total
})

const p = start()
const res = await p
expect(res).toBe(6)
})

test.only("flow support throwing async generators", async () => {
;(Symbol as any).asyncIterator =
(Symbol as any).asyncIterator || Symbol.for("Symbol.asyncIterator")

async function* someNumbers() {
await Promise.resolve()
yield 1
await Promise.resolve()
throw "OOPS"
}

let steps = 0
const start = mobx.flow(async function*() {
let total = 0
for await (const number of someNumbers()) {
total += number
}
return total
})

const p = start()
try {
await p
fail()
} catch (e) {
expect("" + e).toBe("OOPS")
}
})
4 changes: 3 additions & 1 deletion test/tsconfig.json
Expand Up @@ -2,9 +2,11 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"lib": ["esnext"],
"noImplicitAny": true,
"sourceMap": false,
"experimentalDecorators": true,
"strict":true
"strict":true,
"downlevelIteration": true
}
}
1 change: 1 addition & 0 deletions tsconfig.json
Expand Up @@ -13,6 +13,7 @@
"noUnusedLocals": true,
"noImplicitAny": false,
"moduleResolution": "node",
"downlevelIteration": true,
"lib": [
"es6"
]
Expand Down

0 comments on commit cbfbbca

Please sign in to comment.