Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async.apply doesn't work as documented. #129

Closed
jcayzac opened this issue May 10, 2012 · 4 comments
Closed

async.apply doesn't work as documented. #129

jcayzac opened this issue May 10, 2012 · 4 comments

Comments

@jcayzac
Copy link

jcayzac commented May 10, 2012

Despite what the documentation implies, it cannot be used with async.auto.

var fs = require('fs');
var async = require('async');
var cb = function() { console.log(JSON.stringify(arguments, null, 2)) };
var f = async.apply(fs.readFile, 'hello.txt', 'utf-8');

async.parallel([f], cb)
{
  "1": [
    "Hello, World!\n"
  ]
}

async.auto({a:f}, cb)
...cb never gets called...

Same result with f = fs.readFile.bind(null, 'hello.txt', 'utf-8').

@jcayzac
Copy link
Author

jcayzac commented May 10, 2012

Apparently this is because f gets re-bound somewhere by async.auto to some array of functions. If I log this inside f, I get [ [Function] ].

@brianmaissy
Copy link
Contributor

This seems to be a serious problem. @caolan have you seen this?

I agree with @jcayzac that it seems to be an issue with auto, not apply. I'll investigate further

@brianmaissy
Copy link
Contributor

I figured out the issue. When async.auto calls the continuation created by async.apply, it includes an extra 'results' argument (the results of the previous functions) as expected, which is passed on to the original function passed to apply.

So when we create a continuation with

var f = async.apply(fs.readFile, 'hello.txt', 'utf-8');

And then it is called by async.auto like

f(callback, {});

The result is as if we called

fs.readFile('hello.txt', 'utf-8', callback, {});

Which happens never to call the callback, as you can test for yourselves. Whether or not this design decision on the part of the authors of fs is something we agree with, this phenomenon may reappear in any number of places, the crux of the issue being that it isn't necessarily safe to pass extra arguments around to arbitrary functions. Therefore, in order to use the functionality of async.auto safely, all functions MUST be manually wrapped in a way that prevents the results argument from being passed around unintentionally.

I propose adding something to this effect to the documentation of async.auto.

@caolan
Copy link
Owner

caolan commented Mar 2, 2013

yep optional arguments cause all kinds of issues with partial application :( ...I think adding a warning to the readme is the best we can do.

@caolan caolan closed this as completed Mar 2, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants