在JS中进行Currying:将其他变量传递给回调而不更改回调签名

时间:2017-05-15 17:52:03

标签: javascript node.js callback functional-programming currying

我正在使用AWS S3 API包装器。要从云下载文件,请调用以下包装器:

aws.s3.downloadFile(bucket, fileName, cbDownloadOk, cbDownloadErr);

在这个功能中我们构建参数'容器,然后调用官方AWS S3 API:

s3.listObjectsV2(params, function(err, data) {
    if (err) {
        cbDownloadErr(err);         // an error occurred
    } else {
        cbDownloadOk(data);         // successful response
    }
});

现在我希望能够打印下载文件的名称,例如:

var cbDownloadOk = function (data) {
    console.log("File " + fileName + " downloaded");
}

问题在于我无法更改包装器的实现,因此更改了cbDownloadOk回调的签名。

我的问题:
有没有办法在不改变包装器实现的情况下传递给cbDownloadOk fileName?使用全局变量是唯一的方法吗?

更新
我们可以从答案中学习,这个问题涉及currying

2 个答案:

答案 0 :(得分:1)

您正在寻找的可能是curried功能。您可以使用filename来调用它,它会准确地为您提供所需内容:函数只接受一个参数data,并且可以访问其他参数(filename)。

const mySuccessCb = filename => data => {
  // data and name are available here
  console.log("File " + filename + " downloaded");
}

用法:

aws.s3.downloadFile(myBucket, filename, mySuccessCb(filename), cbDownloadErr);

答案 1 :(得分:0)

如果我正确理解您的问题,您只需确保在有权访问cbDownloadOk的范围内定义fileName

aws.s3.downloadFile(
  bucket, 
  fileName, 
  (data) => console.log("File " + fileName + " downloaded"),
  cbDownloadErr
);

或者您可以传递一个调用cbDownloadOkfileName作为附加参数的函数:

aws.s3.downloadFile(
  bucket,
  fileName, 
  (data) => cbDownloadOk(data, fileName),
  cbDownloadErr
);