【问题标题】:javascript abstract callbacks with parameter(s)带有参数的javascript抽象回调
【发布时间】:2019-12-26 00:31:11
【问题描述】:

我试图寻找答案,但我得到的大多数点击都是针对无参数或固定参数的。

我想做的是在一个带有未知数量的参数和参数类型的javascript函数中实现一个可选的回调。

我正在实施一个 javascript 层以使用 AWS 临时凭证来操作 S3 上的文件。一些函数调用上传文件(接收数组),一些删除文件(也是数组),一些重命名存储桶对象(有两个参数,旧键和新键)等。

问题是,当使用临时凭据时,凭据可能会超时。因此,在完成任何呼叫之前,我必须检查凭据是否需要更新。如果他们这样做,我必须先进行异步调用以获取凭据。只有在检索到凭据后,它才应该开始执行它被要求执行的任何操作。

这就是那些“承诺”的全部内容吗?我还没有使用过这些东西,现在正在阅读它们,但不知道如何实现一个(还)。

基本上,在我的代码中,我需要一个用于任何给定 aws 函数的包装器:

function onDelete(key) {
    if(AWS.config.credentials.needsRefresh()) {
        refreshToken(); // makes an asynchronous call with jquery
        // need to do actual delete  when ajax finished: delete(key)
    } else {
        // do actual delete immediately: delete(key)
    }
}
function onRename(oldkey,newkey) {
    if(AWS.config.credentials.needsRefresh()) {
        refreshToken(); // makes an asynchronous call with jquery
        // need to do actual rename when ajax finished: rename(oldkey, newkey)
    } else {
        // do actual rename immediately: rename(oldkey, newkey)
    }
}

或者类似的东西。任何帮助表示赞赏。

【问题讨论】:

  • 你试过传播运算符吗?
  • 在 javascript 中参数始终是可选的,您可以传递多于或少于指定的值。您可以使用 arguments 变量访问所有参数
  • @wendelin 虽然会降低性能并使您的代码通常难以阅读,所以我建议尽可能避免这种情况。
  • @JonasWilms 我不确定它是如何影响性能的,但我同意你应该避免它。我只是想让他意识到参数总是可选的这一事实
  • 所以AWS.config.credentials.needsRefresh() 同步响应?

标签: javascript asynchronous promise callback


【解决方案1】:

使用 spread 和 async / await,您可以构建类似的东西:

  const withCredentials = task => async (...args) => {
        if(AWS.config.credentials.needsRefresh())
          await refreshToken();
       return task(...args);
  } 

用作:

 const onRename = withCredentials(async (oldKey, newKey) => {
   //...
 });

onRename("some", "values")

【讨论】:

  • 我假设第一个例子可以工作,我只是确保 refreshToken 返回 $.ajax()?
  • @scott 是的,没错
【解决方案2】:

您可以为此使用承诺或回调:

基于回调:

function refreshToken(callback) {
  $.ajax({
    success: callback,
    //....
  });
}

function deleteKey(key, callback) {
  // do something asynchronous here, then call callback
  callback({some: 'value'});
}

function onDelete(key, callback) {
    if(AWS.config.credentials.needsRefresh()) {
        refreshToken(() => {
           deleteKey(key, callback);
        });
    } else {
        deleteKey(key, callback);
    }
}


// then you would use it like this:
onDelete("some-key", result => {
  console.log(result); // will be {some: 'value'}
});

如果可以使用 promises & async / await 这会更好:

async function refreshToken() {
  return $.ajax({/* ... */});
}

async function deleteKey(key) {
  // delete the key
}

async function onDelete(key) {
    if(AWS.config.credentials.needsRefresh())
        await refreshToken();
    return deleteKey(key);
}


// then you would use it like this:
onDelete("some-key").then(result => {
  console.log(result); // will be {some: 'value'}
});
// or within an async function:
let result = await onDelete("some-key");

为了使代码更易读/更好,您可以使用HOF(高阶函数):

async function refreshToken() {
  return $.ajax({/* ... */});
}

// higher order function
function withTokenRefresh(fn) {
  return async (...args) => {
    if(AWS.config.credentials.needsRefresh())
      await refreshToken();
    return fn(...args);
  };
}

const onDelete = withTokenRefresh(async key => {
  // todo: delete it
});

const onRename = withTokenRefresh(async (oldkey, newkey) => {
  // todo: rename it
});

如果你使用的是像 babel 这样的编译器,你也可以使用decorators(使用 HOF 的一种更好的方式):

async function refreshToken() {
  return $.ajax({/* ... */});
}

// decorator
function WithTokenRefresh(fn) {
  return async (...args) => {
    if(AWS.config.credentials.needsRefresh())
      await refreshToken();
    return fn(...args);
  };
}

@WithTokenRefresh
async function onDelete(key) {
  // todo: delete it
}

@WithTokenRefresh
async function onRename(oldkey, newkey) {
  // todo: rename it
}

【讨论】:

  • HOF 的文章有点狡猾。作者认为“函数式编程是一种编程形式,你可以将函数作为参数传递给其他函数,也可以将它们作为值返回”,这甚至不接近。他可以继续说好话;我不知道,因为那时我停止阅读了。
  • @Roamer-1888 你是对的,我用更好的链接替换了链接:)
  • 大声笑,哇,他确实假设了很多。不管我是否相信,我只能遵循在其他地方使用的实践来达到我需要的那种结果。如果您知道更好的方法,这就是我问这个问题的部分原因。没有必要屈尊俯就或成为驴子。这就是这些论坛的目的——提出这样的问题。没有得到预判和社论狙击。对不起,我不是每天都为 AWS 编程。我控制的其他系统允许不同的解决方案,不需要根据其他人的规则等待更新过期的凭据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-29
  • 2011-09-08
  • 2017-12-13
  • 1970-01-01
  • 2012-10-11
  • 2021-09-23
  • 1970-01-01
相关资源
最近更新 更多