JavaScript:如何保留一组REST调用返回的数据供以后使用

时间:2014-08-23 15:00:04

标签: javascript

给出以下对象:

var MyObject = function(field1, field2) {
  this.field1 = field1;
  this.field2 = field2;
}

MyObject.prototype.setField1 = functioin(field1) {
  this.field1 = field1;
}

MyObject.prototype.apply = function() {
  ...
  this.setField1("hello");
  log("field1: " + this.field1); // field1 has not been set to "hello"
}

我想更改field1的值......但上面的代码似乎不起作用。我错过了什么吗? TX。

修改

好的,值得为您提供真实案例。下面是我对Swagger的定制处理JWT:

var TokenAuthorization = function(appId, value) {
  this.appId = appId;
  this.value = value;
  this.type = null;
  this.expirationTime = null;
};

TokenAuthorization.prototype.set = function(value, type, expirationTime) {
  this.value = value;
  this.type = type;
  this.expirationTime = expirationTime;
};

TokenAuthorization.prototype.apply = function(obj, authorizations) {
  var now = Math.round(new Date().getTime() / 1000);
  var appId = this.appId;
  var value = this.value;
  var type = this.type;
  var expirationTime = this.expirationTime;

  if (value == null || (type == "browse" && this.expirationTime <= now)) {
    var baseUrl = "http://localhost:9000/auth";
    $.ajax({
      type: "GET",
      url: baseUrl + "/apps/" + appId + "/apikey"
    }).done(function(data) {
      $.ajax({
        type: "POST",
        data: JSON.stringify({ principal: appId, secret: data.apiKey }),
        url: baseUrl + "/apps/credentials",
        contentType: "application/json"  
      }).done(function(data) {
        value = data.token;
        $.ajax({
          type: "GET",
          headers: { "Authorization": "Token " + value },
          url: baseUrl + "/users/credentials"
        }).done(function(data) {
          type = data.token.header.typ.split('/')[1],
          expirationTime = data.token.claims.exp
        })
      })
    });
  }

  this.set(value, type, expirationTime);

  log("token: " + this.value); // value is null
  log("typ: " + this.type); // type is null
  log("exp: " + this.expirationTime); // expirationTime is null

  obj.headers["Authorization"] = "Token " + this.value;
  return true;
};

上面的代码执行三次REST调用以获取令牌,并让客户端应用程序通过API进行浏览。最后,我是如何创建对象的:

window.authorizations.add("authToken", new TokenAuthorization("myApp", null));

由于我将null作为第二个参数(令牌)传递,我需要为当前客户端应用获取browse令牌。那就是它。

我想这个问题与我执行异步REST调用的事实有关。

1 个答案:

答案 0 :(得分:0)

好的,经过一些调试我发现了什么问题。 ajax是异步的,因此apply会立即返回,当然数据仍为null

重写这样的代码解决了问题:

var e = (typeof window !== 'undefined' ? window : exports);

var TokenAuthorization = function(appId, token, type, expirationTime) {
  this.appId = appId;
  this.token = token;
  this.type = type;
  this.expirationTime = expirationTime;
  this.locked = false
};

TokenAuthorization.prototype.lock = function() {
  this.locked = true;
};

TokenAuthorization.prototype.unlock = function() {
  this.locked = false;
};

TokenAuthorization.prototype.apply = function(obj, authorizations) {
  var now = Math.round(new Date().getTime() / 1000);
  if (!this.locked && (this.token == null || (this.type == "browse" && this.expirationTime <= now))) {
    var baseUrl = obj.url.split("api-docs")[0] + "auth";
    var appId = this.appId;
    this.lock();
    $.ajax({
      type: "GET",
      url: baseUrl + "/apps/" + appId + "/apikey"
    }).done(function(result) {
      $.ajax({
        type: "POST",
        data: JSON.stringify({ principal: appId, secret: result.apiKey }),
        url: baseUrl + "/apps/credentials",
        contentType: "application/json"  
      }).done(function(result) {
        var token = result.token;
        $.ajax({
          type: "GET",
          headers: { "Authorization": "Token " + token },
          url: baseUrl + "/users/credentials"
        }).done(function(result) {
          e.authorizations.add("authToken", new TokenAuthorization(
            appId, token,
            result.token.header.typ.split('/')[1],
            result.token.claims.exp
          ));
          log("token: " + token);
          obj.headers["Authorization"] = "Token " + token;
        })
      })
    });
  } else if (!this.locked) {
    obj.headers["Authorization"] = "Token " + this.token;
  }
  return true;
};

这样,如果一个令牌已经存在,它将按原样使用,否则一旦REST调用完成,将设置一个新令牌。