Chaining承诺应对来自this.storage.get()调用的异步承诺

时间:2016-09-14 20:33:44

标签: angularjs asynchronous typescript

我正在努力应对处理我的应用程序中本地存储的异步数据检索,这是用Angular2 / ionic2编写的。

我的代码如下:

  request(args) {
    var headers = new Headers();
    headers.append('Content-Type', 'application/json');

    // Retrieve the token from the local storage, if available
    this.storage.get('token').then((value) => {
      headers.append('Authorization', 'Token ' + value);
    });

    args = args || {};

    var url = this.API_URL + args.url;
    var method = args.method;
    var data = args.data || {};

    var options = new RequestOptions({headers: headers, withCredentials: this.use_session});

    return new Promise((resolve,reject) => {

      if (method == 'GET') {
        this.http.get(url, options)
          .map(res => res.text())
          .subscribe(
            (data:any) => {
              resolve(data);
            },
            (err:any) => {
              data = {};
              data['status'] = 0;
              data['non_field_errors'] = ["Could not connect to server. Please try again."];
              data['error'] = err;
              reject();
            },
            () => {
            }
          );
      }
    });
  }

调用请求函数的代码如下所示:

  authenticationStatus(){
    return this.request({
        'method': "GET",
        'url': "/user/"
      })
      .then((data:any) => {
          console.log('****** authenticationStatus: GET /user/ SUCCESS');
      });
  }

而这反过来就像这样:

      this.djangoAuth.authenticationStatus()
        .then((data:any) => {
            this.loggedIn = true;
            this.enableMenu(true);
            this.root = PhotoPage;
          },
          (err:any)=>{
            this.loggedIn = false;
            this.enableMenu(false);
            this.root = LoginPage;
          });

我很难绕过嵌套的promises,并且无法解决如何修改上面的代码,以便this.storage.get("token")调用的结果在下面的代码中使用之前已将数据添加到标题中。我认为我需要以某种方式将承诺链接起来,但不能确切地知道如何。

1 个答案:

答案 0 :(得分:1)

是的,你需要链接两个承诺 - 它实际上很容易。您所要做的就是从传递给第一个承诺then()方法的回调中返回第二个承诺。

您可以像这样重写代码(我移动了将标题添加到单独函数的代码 - 我认为它更具可读性)

// returns a promise that resolves to headers
createHeaders() {
  var headers = new Headers();
  headers.append('Content-Type', 'application/json');

  // Retrieve the token from the local storage, if available
  return this.storage.get('token').then((value) => {
    headers.append('Authorization', 'Token ' + value);
    return headers;
  });
}

request(args) {

  return this.createHeaders().then(headers => {
    args = args || {};

    var url = this.API_URL + args.url;
    var method = args.method;
    var data = args.data || {};

    var options = new RequestOptions({headers: headers, withCredentials: this.use_session});

    return new Promise((resolve,reject) => {

      if (method == 'GET') {
        this.http.get(url, options)
          .map(res => res.text())
          .subscribe(
            (data:any) => {
              resolve(data);
            },
            (err:any) => {
              data = {};
              data['status'] = 0;
              data['non_field_errors'] = ["Could not connect to server. Please try again."];
              data['error'] = err;
              reject();
            },
            () => {
            }
          );
      }
    });
  });
}

所有这一切中最困难的事情就是不要忘记每一个必要的return

此外,我注意到,如果Promise收到GET以外的任何其他方法,您的else将永远无法完成 - 您可能希望reject部分添加if (method == 'GET') { .... } else { reject(new Error('invalid method:' + method)); }

operator()