如何实现Ionic / Cordova内部的承诺

时间:2017-07-13 08:26:37

标签: angular cordova typescript ionic-framework ionic2

我正在构建一个使用基于令牌的身份验证的Ionic应用程序。当用户授权访问令牌存储在本地存储中时。

然后,我的代码会向提供商调用所需的任何数据(在这种情况下,它会从API中提取'培训程序)。

反过来,该提供程序调用另一个处理我的API的HTTP请求的提供程序。它有效地设置所需的标头并启动HTTP请求,然后将响应返回给请求的提供者。

一切正常,直到我需要在发出HTTP请求之前从存储中获取访问令牌。从存储中访问数据似乎不是即时的,而是使用then语法。

似乎当我从我的代码中调用提供程序时,它会传递给Training Programs提供程序,然后传递给API提供程序。然后,这里的代码会运行并重新传递,但这会在我的应用程序有机会从存储中获取所需内容之前发生。

我尝试在then方法的storage.get调用中将所有内容放入请求中,但这不起作用。

这是我的请求代码:

this.trainingProgramme.get_programmes().subscribe((res) => {
  loader.dismiss();
  console.log(res);
});

哪些过滤到我的trainingProgramme提供商:

  get_programmes() {
    let seq = this.api.get('training-programmes');

    seq
      .map(res => res.json())
      .subscribe();

    return seq;
  }

反过来传递给我的api提供商:

export class Api {
  base_url: string = 'https://******.com';
  url: string = this.base_url + '/api/v1';      
  access_token: string;

  constructor(
    public http: Http, 
    private storage: Storage) {

    // Grab access token and store it
    storage.get('access_token').then((val) => {
      console.log('Pulled access token from local storage', val);
      this.access_token = val;
    });
  }

  // Performs a GET request with auth headers
  get(endpoint: string, params?: any) {
    let headers = new Headers();
    headers.append('Authorization', 'Bearer ' + this.access_token);

    let options = new RequestOptions({ headers: headers });

    return this.http.get(this.url + '/' + endpoint, options);
  }
}

这不会产生任何错误,但发送的标题是:

Authorization: Bearer undefined

总结:我认为storage调用是异步发生的,因此HTTP调用在有机会获取访问令牌之前就已启动。在调用HTTP请求之前,如何防止这种情况发生或等待storage完成?只需将我的代码放在then内就行了,因为这个方法已经在subscribe内了,所以我收到了错误。

更新1:

下面是我使用的代码将storage代码放在方法本身而不是构造函数中,然后将所有代码(包括HTTP调用)放在then中。

  // Performs a GET request with auth headers
  get(endpoint: string, params?: any) {
    // Grab access token and store it
    this.storage.get('access_token').then((val) => {
      console.log('Pulled access token from local storage', val);
      this.access_token = val;

      let headers = new Headers();
      headers.append('Authorization', 'Bearer ' + this.access_token);

      let options = new RequestOptions({ headers: headers });    

      return this.http.get(this.url + '/' + endpoint, options);
    });
  }

错误:

Runtime Error
Uncaught (in promise): 
TypeError: Cannot read property 'map' of undefined 
TypeError: Cannot read property 'map' of undefined at TrainingProgramme.get_programmes 

大概这是因为get方法在预期时没有返回任何内容,因为返回现在是异步的。

2 个答案:

答案 0 :(得分:1)

试试这个:)

yourlongmethod() {

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

     //your code
     var data = "Any data you want to return with the promise";

    resolve(data);
  });

}

然后你可以调用这个

  

yourlongmethod()。then((res)=> {

     

console.log(res)})

答案 1 :(得分:0)

在您的api提供程序的构造函数中,您正在编写用于获取异步存储数据的代码,请记住JavaScript是同步的,因此一旦异步被调用,我的意思是store.get().then()它就完成了构造函数部分它没有等待将值存储到this.access_token,而是调用get()函数。

为了告诉storage.get异步调用等待它完成,然后去调用get()方法,只需使用关键字asyncawait < / p>

constructor(
    public http: Http, 
    private storage: Storage) {

   this.getAccessToken(); //only after completing this function it will go the next command
  }

  async getAccessToken(){
      // Grab access token and store it
      //below i have writen await inorder to wait until this is completed.
    const token = await storage.get('access_token').then((val) => {
      console.log('Pulled access token from local storage', val);
      this.access_token = val;
    });
  }

尝试放置上面的代码并检查希望它可以帮助你