在 JS 中柯里化:在不更改回调签名的情况下将附加变量传递给回调

Currying in JS: Pass additional variable to callback without changing the callback signature

我正在使用 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.

如果我对你的问题的理解正确,你只需要确保 cbDownloadOk 定义在可以访问 fileName:

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

或者您可以传递一个调用 cbDownloadOk 的函数,并将 fileName 作为附加参数:

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

您要查找的可能是 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);