【问题标题】:Waiting for the result of a function called from somewhere else等待从其他地方调用的函数的结果
【发布时间】:2021-07-01 02:10:04
【问题描述】:

我有一个节点服务器,我想在其中集成 Paypal。我有一个模块应该从贝宝返回访问令牌。这个模块有一个异步函数,看起来像这样:

let token: string | null = null;

export async function getToken() {
    if (token === null) {
        token = await requestTokenFromPaypal()
    }

    return token;
}

export function resetToken() { token = null }
main:
getToken()
getToken()
getToken()
// -> I want all calls to wait until the first request for the token is finished and then resolve to the token
// -> Currently the token will be requested three times

如果其他请求产生 401 并且令牌无效,则调用 resetToken 函数。所以需要一个新的令牌。但是现在每次调用 getToken 都会产生一个令牌请求,直到第一个请求完成并保存到令牌。

那么我如何才能等待从另一段代码调用的另一个函数的结果呢?我已经考虑过保存承诺或类似的事情,但我无法接受它。

我也尝试用谷歌搜索,但只得到标准的异步代码问题。如果您发现其他类似问题,请参考我。

【问题讨论】:

  • 请描述您在代码中尝试执行的操作。例如,你如何调用你的函数?不要忘记在 getToken 函数中将 token 分配给 await requestTokenFromPaypal() 的结果。而且您不需要返回已解决的承诺。 async 函数已经返回了一个 promise,从该函数返回将与执行 return token 相同。
  • 感谢您的回复。我将编辑问题

标签: javascript node.js paypal async-await promise


【解决方案1】:

只需返回一个承诺,然后.then它。

let token: string | null = null;

export async function getToken() {
    if (token === null) {
        return requestTokenFromPaypal() // this function should return a promise
        /* (node-fetch would be the easiest way to do that, but whatever works) */
    }

    return Promise.resolve(token);
}

export function resetToken() { token = null }


//later, somewhere else in your code
getToken().then(function(token) {
  //do something with 'token'
});

【讨论】:

  • 感谢您的回复。我想避免多次调用 requestTokenFromPaypal。但是,如果我现在在设置令牌之前多次调用 getToken,则该函数会被多次调用
  • 如果您按照我上面的解释进行操作,则无需担心
  • 除了null 之外,您从不在token 中存储任何东西?
  • 它是全局的,所以我认为它是从requestTokenFromPaypal 设置的,但可以通过这个 getToken 来完成。无论哪种方式都有效。
  • 我无法控制何时调用 getToken。因此,如果两个人同时访问某个链接,getToken() 会同时被调用,因此他们都会运行 requestTokenFromPaypal 而不会等待函数的一次执行。我认为 IAmDranged 建议的令牌存储是更好的解决方案
【解决方案2】:

您可以检查令牌的请求是否已经开始,而不是检查令牌是否可用。

您可以通过检查 tokenPromise 来做到这一点,它基本上只是令牌的包装器。

let tokenPromise = null

export async function getToken() {
    if (!tokenPromise) {
        tokenPromise = requestTokenFromPaypal()
    }

    return tokenPromise
}

export function resetToken() { tokenPromise = null }

如果您想知道,直接返回 tokenPromise 而不等待它实际上与等待它然后返回令牌的效果相同。

【讨论】:

  • 我想这正是我要寻找的!谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 1970-01-01
  • 2020-09-27
  • 1970-01-01
  • 2020-01-19
相关资源
最近更新 更多