Ionic 2 - 存储空间始终为空,直到重新加载应用程序

Ionic 2 - Storage always empty until reloading the app

我目前正在使用 Ionic 2 构建一个应用程序并使用存储插件来保存我的值,这些值几乎只是一个 API 令牌和用户配置文件,因为该应用程序从 API.

我正在通过 ionic serve 测试应用程序,因为没有使用本机函数,但现在我面临的问题是每次我在存储中存储一个值时,在我重新加载应用程序之前都无法访问该值有点烦人,因为在用户登录后,他被重定向到需要 API 令牌的页面,该令牌在我重新加载应用程序之前不可用,因此整个过程陷入循环。

Ionic Storage 在浏览器中使用 IndexedDB,当我使用 Chrome 开发人员工具检查这些值时,我可以看到这些值已存储。

我一直在努力找出问题所在,但在重新加载应用程序之前找不到存储值不可用的任何原因。

import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage';
import { HttpClientService } from './http-client-service';
import 'rxjs/add/operator/map';

@Injectable()
export class AuthService {
    constructor(public events: Events, public storage: Storage, public http: HttpClientService) {
        //
    }

    login(user) {
        var response = this.http.post('login', {
            email: user.email,
            password: user.password,
        });

        response.subscribe(data => {
            this.storage.set('api_token', data.token);

            console.log('raw : ' + data.token); // shows the api token

            this.storage.get('api_token').then((value) => {
                console.log('storage : '+ value); // is empty...
            });
        });

        return response;
    };
}

编辑:我设法将问题追查到存储 运行 异步导致令牌未添加到 headers.

createAuthorizationHeader(headers: Headers) {
    // this does add the header in time
    localStorage.setItem('api_token', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vYXBpLndpaHplLmRldi9sb2dpbiIsImlhdCI6MTQ4MTE4MzQyOCwiZXhwIjoxNDgxMTg3MDI4LCJuYmYiOjE0ODExODM0MjgsImp0aSI6IjdlNTE1WUEwWmE4NWc2QjUiLCJzdWIiOiIxIiwidXNlciI6eyJpZCI6MX19.T4KpqgCB8xU79vKyeLG4CJ0OHLpVI0j37JKIBJ_0CC4');
    headers.append('Authorization', 'Bearer ' + localStorage.getItem('api_token'));

    // this does not add the header in time
    return this.storage.get('api_token').then((value) => {
        headers.append('Authorization', 'Bearer ' + value);
    });
}

getHeaders(path) {
    let headers = new Headers();
    headers.set('Accept', 'application/json');
    headers.set('Content-Type', 'application/json');

    if(!this.isGuestRoute(path)) {
        this.createAuthorizationHeader(headers);
    }

    return new RequestOptions({ headers: headers });
}

get(path: string) {
    return this._http.get(this.actionUrl + path, this.getHeaders(path))
        .map(res => res.json())
        .catch(this.handleError);
}

好吧,看了 ionic docs 我明白为什么你把它们放在彼此下面,因为它们也像文档中那样显示。

但是Storage.set(key, value):

Returns: Promise that resolves when the value is set

这意味着您不能按照您使用它的方式使用它(因此他们添加了带有 //or ....

的评论

因为解决 Promise 是异步的。

如果你想像你当前使用的那样使用这个值(这看起来有点奇怪,但你可能会测试这个值是否设置正确)你应该使用

this.storage.set('api_token', data.token).then(() => {
   this.storage.get('api_token').then((value) => {
       console.log('storage : '+ value); // is empty...
    });
});

console.log('raw : ' + data.token); // shows the api token

如果您想了解更多关于为什么会发生这种情况的信息,请查看这个 SO 答案(我更喜欢第二个)Asynchronous vs synchronous execution, what does it really mean?