javascript - 当存在 constructor() 时调用异步函数

标签 javascript asynchronous ecmascript-6 axios token

我有一个异步函数,如果用户的 token 过期,它会生成一个新的 token 。我将异步函数代码复制并粘贴到该项目中,并且类和构造函数已经构建。

我想调用异步函数,但我不确定如何/在哪里调用,特别是在存在构造函数的情况下。我可以看到其他异步函数的调用方式和位置(即 var _token = wait sessionGet(_tokenName)),但由于我要调用的异步函数是最外层的异步函数(如果这有意义的话) )我不确定在哪里调用它。

这是我所知道的(如果我错了请纠正我):

  • 我无法在异步函数之外使用 await

  • 构造函数返回Promise是一种不好的做法

  • 我的异步函数必须是异步的,否则它会“破坏代码其余部分的流程”——async被多次使用全程次数

export default class {
  constructor() {
    this.setTokenVar();
    // other function calls
  }

  setTokenVar() {

    async function permissionToCallAPI() { // -------- this is what I want to call
      const _tokenName = "tokenSet",
        _RestHost = "https://.../.../api";
      async function sessionGet(key) {
        let stringValue = window.sessionStorage.getItem(key);
        if (stringValue != null) {
          try {
            const {
              value,
              expirationDateStr
            } = JSON.parse(stringValue);

            if (value && expirationDateStr) {
              let expirationDate = new Date(expirationDateStr);

              if (expirationDate <= new Date()) {
                throw "Expired Token";
              }

              const isValid = await isAuthorized(value.value);

              if (isValid) {
                console.log("Valid Token");
                return value;
              } else {
                throw "Expired Token";
              }
            } // if (value && expirDateStr)
          } catch (e) {
            console.log(e);
            window.sessionStorage.removeItem(key);
          }
        }
        return null;
      }
      async function isAuthorized(key) {
        let ret = false;
        await axios.post(_RestHost + "/User/GenerateToken", null, {
            withCredentials: true,
            async: false,
            headers: {
              "accept": "application/json;odata=verbose",
              "content-type": "application/json",
              "Authorization": key
            }
          }).then(resp => {
            ret = true;
          })
          .catch(err => {
            console.log("Failed Authentication.");
          });

        return ret;
      }

      // add into session
      function sessionSet(key, value, expirationInMin) {
        if (!expirationInMin) {
          expirationInMin = 59;
        }

        var expirationDate = new Date(
          new Date().getTime() + 60000 * expirationInMin
        );

        var newValue = {
          value: value,
          expirationDateStr: expirationDate.toISOString()
        };

        window.sessionStorage.setItem(key, JSON.stringify(newValue));
      }

      var _token = await sessionGet(_tokenName);

      if (_token == null) {
        let request = axios
          .get(_RestHost + "/User/GenerateToken", {
            withCredentials: true
          });

        return request
          .then(response => {

            const authToken = response.data.AuthToken;

            sessionSet(_tokenName, authToken);

            return authToken;
          })
          .catch(err => {
            throw err;
          });
      } else {
        return _token;
      }

    } // permToCallAPI

  } // setTokenVar()
}

最佳答案

除了在构造函数中设置变量之外,执行任何操作都是 considered an anti-pattern .

最简单的解决方案是让调用者负责调用 obj.setTokenVar()这可能是一个异步函数。

由于在调用该方法之前对象的状态可能不一致,因此您可以创建一个工厂异步函数来保证对象在让调用者使用它之前完全初始化。

export async createThing() {
   const obj = new Thing();
   await obj.setTokenVar();
   return obj;
}

旁注 async可以从非异步函数调用,但不能使用await,必须使用then所有异步函数都返回的 Promise。

function doSomething() {
   createThing().then(thing => console.log(thing))
}

function async doSomething() {
   console.log(await createThing())
}

关于javascript - 当存在 constructor() 时调用异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57908481/

相关文章:

javascript - 我的全日历上没有显示任何事件。 (来自谷歌日历)

javascript - 如何用两个过滤器制作一个过滤器?

javascript - AngularJs $http post 在操作钩子(Hook)之前

asynchronous - MeteorwrappAsync没有方法 'apply'

javascript - 如何使用无效变量名的键名解构对象属性?

ecmascript-6 - es6 模块是否否定了对 browserify/webpack 的需求?

javascript - 如何使用 jquery 为我附加一个 div,其中还包括所有嵌套的 div?

c# - 客户端异步 WCF 与服务器端异步 WCF

javascript - 如何选择通过 jQuery load() 函数加载的元素?

javascript - 这个生成器如何返回 3?