代码之家  ›  专栏  ›  技术社区  ›  gonephishing

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

  •  1
  • gonephishing  · 技术社区  · 7 年前

    2.6.1

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

    你做了什么?请附上一个最小的可复制的案例来说明这个问题。

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

    你以为会发生什么?

    实际结果如何?

    同样的代码在版本2.0.1中执行得很好,但是在升级到2.6.1之后,它已经停止工作,对我们来说非常重要。任何解决办法也将不胜感激。

    2 回复  |  直到 7 年前
        1
  •  3
  •   Jaromanda X    7 年前

    基于 documentation

    无论我们在哪里接受节点样式的异步函数,我们也直接接受ES2017异步函数。在这种情况下,将不会向异步函数传递最终回调参数,任何抛出的错误都将用作隐式回调的err参数,返回值将用作结果值(i、 e.拒绝返回的承诺成为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);
        }],
    })
    
        2
  •  1
  •   ZorgoZ    7 年前

    只是官方的复印件 documentation

    无论我们在哪里接受节点样式的异步函数,我们也直接 接受ES2017异步函数。在本例中,异步函数 将 不能传递最后的回调参数 用作隐式回调的err参数,返回 值将用作结果值(i、 被拒绝的 值成为结果。)