Skip to content

Commit

Permalink
Upstream repo.parallel fix
Browse files Browse the repository at this point in the history
We encountered an issue on an app using 12.12.x where we needed the
payloads from `repo.parallel` when it completed. This commit upstreams
that change.
  • Loading branch information
nhunzaker committed Nov 13, 2017
1 parent 2eea38e commit 68435ea
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 11 deletions.
8 changes: 5 additions & 3 deletions packages/microcosm/docs/api/microcosm.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,16 +333,18 @@ fork.push(getPeople)

Create a new "group" action bound to the resolution of a list of
actions. If all actions resolve or cancel, the group action will
resolve. If any action is rejected, the group action fails:
+resolve. If any action is rejected, the group action fails. If all
actions resolve, their respective payloads will be available in the
`onDone` callback:

```javascript
let group = repo.parallel([
repo.push(actionOne),
repo.push(actionTwo)
])

group.onDone(function () {
console.log('hurrah!')
group.onDone(function ([answer1, answer2]) {
console.log('hurrah!', answer1, answer2)
})
```

Expand Down
20 changes: 12 additions & 8 deletions packages/microcosm/src/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,23 +189,27 @@ class Action extends Emitter {
*/
link(actions: Action[]): this {
let outstanding = actions.length
let answers = []

const onResolve = () => {
if (outstanding <= 1) {
this.resolve()
} else {
outstanding -= 1
}
if (actions.length === 0) {
return this.resolve(answers)
}

actions.forEach(action => {
let onResolve = answer => {
answers[actions.indexOf(action)] = answer
outstanding -= 1

if (outstanding <= 0) {
this.resolve(answers)
}
}

action.onDone(onResolve)
action.onCancel(onResolve)
action.onError(this.reject)
})

onResolve()

return this
}

Expand Down
63 changes: 63 additions & 0 deletions packages/microcosm/test/unit/action/link.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Microcosm } from 'microcosm'

function delay(payload, n) {
return new Promise(resolve => setTimeout(() => resolve(payload), n))
}

const cancels = () => {
return action => action.cancel()
}

const rejects = () => {
return action => action.reject()
}

describe('Action link', function() {
it('remembers and returns the results of each child action', async function() {
const repo = new Microcosm()

const action = repo.parallel([
repo.push(() => delay(1, 20)),
repo.push(() => delay(2, 10)),
repo.push(() => delay(3, 15))
])

let payload = await action

expect(payload).toEqual([1, 2, 3])
})

it('resolves empty', async function() {
const repo = new Microcosm()

const action = repo.parallel([])

let payload = await action

expect(payload).toEqual([])
})

it('handles cancelled actions by just returning undefined in that position', function() {
const repo = new Microcosm()

const action = repo.parallel([
repo.push(() => 1),
repo.push(cancels),
repo.push(() => 3)
])

expect(action.payload).toEqual([1, undefined, 3])
})

it('rejects if any of the actions reject', function() {
const repo = new Microcosm()

const action = repo.parallel([
repo.push(rejects),
repo.push(() => 2),
repo.push(() => 3)
])

expect(action.status).toEqual('reject')
})
})

0 comments on commit 68435ea

Please sign in to comment.