Skip to content

Instantly share code, notes, and snippets.

@kevinmehall
Created September 14, 2012 22:27
Show Gist options
  • Save kevinmehall/3725341 to your computer and use it in GitHub Desktop.
Save kevinmehall/3725341 to your computer and use it in GitHub Desktop.
Async find/replace in CoffeeScript
# Replace parts of `string` matching regex `pattern` with the callback value of an
# async function `fn`, which receives the regex match object and callback. Calls `cb` with
# final string when complete.
asyncReplace = (string, pattern, fn, cb)->
console.assert(pattern.global, "asyncReplace pattern must be global (g flag)")
outChunks = []
lastIndex = 0
pendingCb = 0
# prevent final callback until the string has been fully processed
done = ->
while (m = pattern.exec(string))
# keep the string between the end of last match and beginning of this one
# and reserve a spot in the array for the callback result
insertionPoint = outChunks.push(string.slice(lastIndex, m.index), undefined) - 1
lastIndex = m.index + m[0].length
pendingCb++
do (insertionPoint) ->
fn m, (result) ->
outChunks[insertionPoint] = result
done(--pendingCb)
# keep text after last match
outChunks.push(string.slice(lastIndex))
# allow completion callback now
done = ->
if pendingCb == 0
cb(outChunks.join(''))
# and check it, in case there are no pending callbacks
done()
@tcr
Copy link

tcr commented Sep 15, 2012

What's the use for this? Neat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment