在async.auto链中使用async / await会导致TypeError:回调不是函数

时间:2018-09-25 05:41:55

标签: javascript async-await async.js

您使用的是哪个版本的异步?

2.6.1

(节点版本/浏览器版本)在哪个环境中发生了问题

8.11.3

您做了什么?请提供一个可重复的最小案例来说明问题。

假设fileObj是从外部提供的:

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);
  }],
})

您期望发生什么?

collectData完成执行后,filterData应该开始执行在collectCB函数内部传递的参数

实际结果是什么?

TypeError:collectCB不是函数。

同一代码在2.0.1版中可以很好地执行,但是升级到2.6.1之后,它已经停止工作,这对我们来说至关重要。任何解决方法也将不胜感激。

2 个答案:

答案 0 :(得分:2)

基于documentation(已在其他答案中引用,但这里又是)

  

无论我们接受Node风格的异步函数,还是直接接受ES2017异步函数。在这种情况下,异步函数将不会传递给最终的回调参数,并且任何引发的错误都将用作隐式回调的err参数,而返回值将用作结果值。 (即拒绝返回的Promise成为err回调参数,而解析的值成为结果。)

你会做的

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);
        }
    },
    //                                      Note, no callback as per documentation
    collectData: ['download', async (results) => {
        console.log(typeof results); // prints correct object

        let res = await anHttpRequest();

        if (res.response && res.response.statusCode == 200) {
            // this return is equivalent to callback(null, value);
            return 'fileCombined.txt';
        } else if (res.response.statusCode >= 300) {
            // this throw is equivalent to callback(err);
            throw new Error('Request failed inside async-auto');
        }
        // but surely something should be here!? for status code 201-209?
    }],

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

答案 1 :(得分:1)

只需复制官方https://github.com/rodriguezcommaj/principles-of-email-design上的粘贴内容:

  

无论我们接受Node样式的异步功能,我们都直接   接受ES2017异步功能。在这种情况下,异步功能将   不会传递最终的回调参数,并且将抛出任何错误   用作隐式回调的err参数,并返回   值将用作结果值。 (即拒绝   返回的Promise成为err回调参数,并且已解决   值成为结果。)