Skip to content

Commit

Permalink
Merge pull request #2923 from taion/loopAsync-unwind-recursion
Browse files Browse the repository at this point in the history
Unwind recursion in loopAsync when possible
  • Loading branch information
timdorr committed Jan 18, 2016
2 parents 95a0237 + fe2148b commit d8eed68
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 13 deletions.
36 changes: 32 additions & 4 deletions modules/AsyncUtils.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
export function loopAsync(turns, work, callback) {
let currentTurn = 0, isDone = false
let sync = false, hasNext = false, doneArgs

function done() {
isDone = true
if (sync) {
// Iterate instead of recursing if possible.
doneArgs = [ ...arguments ]
return
}

callback.apply(this, arguments)
}

function next() {
if (isDone)
if (isDone) {
return
}

hasNext = true
if (sync) {
// Iterate instead of recursing if possible.
return
}

sync = true

if (currentTurn < turns) {
while (!isDone && currentTurn < turns && hasNext) {
hasNext = false
work.call(this, currentTurn++, next, done)
} else {
done.apply(this, arguments)
}

sync = false

if (isDone) {
// This means the loop finished synchronously.
callback.apply(this, doneArgs)
return
}

if (currentTurn >= turns && hasNext) {
isDone = true
callback()
}
}

Expand Down
35 changes: 26 additions & 9 deletions modules/matchRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,26 @@ import { createRoutes } from './RouteUtils'

function getChildRoutes(route, location, callback) {
if (route.childRoutes) {
callback(null, route.childRoutes)
} else if (route.getChildRoutes) {
route.getChildRoutes(location, function (error, childRoutes) {
callback(error, !error && createRoutes(childRoutes))
})
} else {
callback()
return [ null, route.childRoutes ]
}
if (!route.getChildRoutes) {
return []
}

let sync = true, result

route.getChildRoutes(location, function (error, childRoutes) {
childRoutes = !error && createRoutes(childRoutes)
if (sync) {
result = [ error, childRoutes ]
return
}

callback(error, childRoutes)
})

sync = false
return result // Might be undefined.
}

function getIndexRoute(route, location, callback) {
Expand Down Expand Up @@ -116,7 +128,7 @@ function matchRouteDeep(
// Either a) this route matched at least some of the path or b)
// we don't have to load this route's children asynchronously. In
// either case continue checking for matches in the subtree.
getChildRoutes(route, location, function (error, childRoutes) {
const onChildRoutes = (error, childRoutes) => {
if (error) {
callback(error)
} else if (childRoutes) {
Expand All @@ -135,7 +147,12 @@ function matchRouteDeep(
} else {
callback()
}
})
}

const result = getChildRoutes(route, location, onChildRoutes)
if (result) {
onChildRoutes(...result)
}
} else {
callback()
}
Expand Down

0 comments on commit d8eed68

Please sign in to comment.