2016-09-14 152 views
0

我很努力应付处理我的应用程序,这是写在Angular2/ionic2本地存储数据的异步检索。链接承诺,以应付来自this.storage.get()调用异步承诺

我的代码如下:

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; 
 
      });

我有困难的包裹我的头周围嵌套的承诺,不能工作了如何修改上面的代码,以便this.storage.get("token")调用的结果在下面的代码中使用之前已将数据添加到标题中。我认为我需要以某种方式将承诺链接起来,但不能确切地说明如何。

+0

本地localStorage的访问添加else部分是同步的......不知道为什么你的被包裹在承诺 – charlietfl

+1

这不是原生它是angularjs /离子 –

+0

这两个框架都使用本机javascript – charlietfl

回答

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永远不会完成 - 你可能要与reject

if (method == 'GET') { 
    .... 
} else { 
    reject(new Error('invalid method:' + method)); 
} 
+0

似乎有一个问题参数的范围。代码落在使用args.url和args.method的行上。 –

+0

我使用Typescript以防有任何区别。 –

+0

是的,我忘了'这个'。调用createHeaders()时需要它,并且在回调中需要它(这就是为什么我将'function'改为'=>')的原因。固定。 – artem