Some noteworthy tips and gotchas:
A "Streamline function" means a function written in Streamline syntax. For scripts, the top level counts. (But don't make Streamline calls at the top level in modules, since Node's
require()isn't async / won't wait!)
When calling a Streamline function, you must pass a callback always. (This wasn't the case pre-Streamline-0.10; you could pass
null, or omit the callback altogether. No longer w/ Streamline 0.10.)
logger.ifErroris always available, and it's a great "best practice" to log async errors anyway (so that they're not silently swallowed). And, that works even from non-Streamline functions, e.g. event listeners.
update = (file, _) -> # ... file.on 'change', -> update file, logger.ifError 'File update failed!'
If you want to kick off an async call but still make use of the results later, you can pass
!_as the callback to get a future. The most typical use case for this is parallelization, and Streamline offers a
flows.collectutility for doing that directly.
flows = require 'streamline/lib/util/flows' users = flows.collect _, User.getById id, !_ for id in userIds
If you want to kick off an async task inline, using an IIFE is a nice shorthand approach. Define it with
_, but invoke it with a callback:
# some work before # ... do (_=logger.ifError 'Inline async task failed!') -> waitForSomething _ thenSomethingElse _ # ... # some work immediately after, not waiting for the above
(You could also pass
!_instead of a callback to have the IIFE return a future.)
This is also useful if you want to write some Streamline code but you're in a non-Streamline function. (We don't generally encounter that case, though.)
Similarly, if you need external (third-party) code to invoke a Streamline function, you must get it to pass a callback, too. Hopefully the code you're using can do this. E.g.
setTimeout (_) -> someAsyncTask _ , 500, logger.ifError 'Delayed async task failed!'
If it can't (e.g.
process.nextTick()), you need to create a non-Streamline wrapper that calls your Streamline function w/ a callback. Fortunately, you can use
Function#bind()to shorthand that:
process.nextTick ((_) -> someAsyncTask _ ).bind(@, logger.ifError 'Delayed async task failed!')
_is a reserved character in Streamline code, we can't use it as the variable for Underscore.js. So we use
$instead, since we don't use jQuery on the server-side, and Underscore is a jQuery-like utility anyway.
If you have any issues or questions, talk to @aseemk!