Async: Using async / await inside async.auto chain leads to TypeError: callback is not a function

Created on 24 Sep 2018  ·  5Comments  ·  Source: caolan/async

What version of async are you using?
2.6.1

Which environment did the issue occur in (Node version/browser version)
8.11.3

What did you do? Please include a minimal reproducible case illustrating the issue.
Assuming fileObj is supplied from outside:

async.auto({
  download: (downloadCB) => {
    if (fileObj) {
      fs.writeFile(__dirname + ‘fileNew.txt’, fileObj.content, 'base64', function (err) {
        if (err){
          return downloadCB(err);
        }
        return downloadCB(null , fileObj.generatedFileName); // works fine
      });
    } else {
      let err = new Error('File not found');
      return downloadCB(err);
    }
  },
  collectData: ['download', async (results, collectCB) => {
    console.log(typeof collectCB); // prints undefined
    console.log(typeof results); // prints correct object

    let res = await anHttpRequest();
    if (res.response && res.response.statusCode == 200) {
      return collectCB(null , 'fileCombined.txt'); // This is where the ISSUE happens
    }
    else if(res.response.statusCode >= 300) {
      return collectCB(new Error('Request failed inside async-auto'));
    }
  }],

  filterData: ['collectData', (results, filterCB) => {
    doFilter(results.collectData, filterCB);
  }],
})

What did you expect to happen?
After collectData finishes execution, filterData should begin execution the param passed inside collectCB function

What was the actual result?
TypeError: collectCB is not a function.

The same code executes well with version 2.0.1 but after upgrade to 2.6.1 it has stopped working and its critical for us. Any work arounds will also be appreciated.

docs question

Most helpful comment

We treat async functions differently -- we do not pass them a callback. Instead, simply return a value (or throw an error).

All 5 comments

We treat async functions differently -- we do not pass them a callback. Instead, simply return a value (or throw an error).

Yes, learnt about the same from StackOverflow and so posting a reference to same here, in case someone stumbles upon this in future: Using-async-await-inside-async-auto-chain

This also applies to async.parallel if the functions are async you need to return the value not call the callback. This should get added to the documentation and examples.

        async.parallel({
            // NOTE: for async functions just return value or throw error
            // don't use the callback
            dates: async function(callback) {
                var rr = await getDates(dbName, r.indi, idx);
                return rr;
             },
             sdates: async function(callback) {
                  var rr = await getDates(dbName, r.spouse, idx);
                  return rr;
             },
             cdates: async function(callback) {
                  var rr = await getDates(dbName, r.cindi, idx);
                  return rr;
             }
        },
        function(err, results) {
             console.log(results);
        });

I'd like to re-write a lot of the examples in the docs to use more async/await, to highlight what you can do now.

More than features in this package, we need docs. Will be great to see more examples in the future

Was this page helpful?
0 / 5 - 0 ratings