离子存储“得到”仅在方法内的第二次调用时返回null [英] Ionic storage "get" returns null only on the second call within method

查看:151
本文介绍了离子存储“得到”仅在方法内的第二次调用时返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正面临着Ionic Storage的一个非常奇怪的问题。我有一个方法从存储中读取一个值并返回一个包含对应的对象的promise:

I am facing a very strange issue with Ionic Storage. I have a method that reads a value from the storage and returns an a promise containing an object corresponding to that:

private getAuthorizedOptions(): Promise<RequestOptions>
  {
        return this._storage.get('bdAccessToken')
            .then(v => {
                console.log("access token: ", v);
                let token = v;
                let header = new Headers({
                    'Authorization': 'Bearer ' + token
                });
                let ro = new RequestOptions({
                    headers: header
                });
                let options = new RequestOptions();
                if (options.headers) options.headers.delete("Authorization");
                options.headers = header;
                return options;
            });
  }

现在我有另一个方法,它会在链中调用上面的方法两次动作:

Now I have another method, which will call this above method twice within a chain of actions:

get(url:string, options?:RequestOptions): Observable<Response>
    {   
        return Observable.fromPromise(this.getAuthorizedOptions())
                .mergeMap((options) => 
                {
                    return super.get(url, options)
                        .catch(err => {
                            if (err && err.status === 401) 
                            {
                                return this._authService.refreshToken()
                                    .mergeMap(r => 
                                        {
                                            return Observable.fromPromise(this.getAuthorizedOptions())
                                                .mergeMap(opt => {
                                                    return super.get(url, opt)
                                            });

                                        }
                                    )
                                    .catch(err2 => {
                                        console.log("redirecting.");
                                        this.redirect();
                                        return Observable.throw(err2);
                                    });
                            }
                            else {
                                return Observable.throw(err);
                            }
                        });
                });
    }

现在跟踪这些方法显示出一些奇怪的东西。第一次调用getAuthorizedOptions()方法时,它可以很好地从存储中读取bdAccessToken值。第二次调用它时,返回的值为NULL。

Now tracing these methods shows something strange. The first time the "getAuthorizedOptions()" method is called, it can read the "bdAccessToken" value from the storage very well. The second time it is called, the returned value is NULL.

我已经把头发拉了两天了,任何帮助都表示赞赏,就像你从来没有被赞赏过一样之前!大声笑!

I have been pulling my hair for two days on this, any help is appreciated like you have never been appreciated before! lol!

推荐答案

我遇到了一些存储问题和古怪行为,最终与异步问题有关。

I had some issues with storage, and quirky behaviour, that ended up being related to asynchronous issues.

未按预期/预期顺序执行的事项。

Things not executing in the desired/expected sequence.

所以我最终让我的服务有状态并监控了一个BehaviourSubject事件。

So I ended up making my service stateful and monitor for a BehaviourSubject event instead.

import { Injectable }       from '@angular/core';
import { Storage }          from '@ionic/storage';
import { Server }           from './../model/server';
import { Subscription }     from 'rxjs/Subscription';
import { BehaviorSubject }  from "rxjs/BehaviorSubject";

export class LoginService {
  private static readonly SERVER = 'server';
  private servers$:BehaviorSubject<Server[]>;
  private servers: Server[];
  public serversSubs:Subscription

  constructor(public storage: Storage) {

    this.servers$ = new BehaviorSubject([] as Server[]);
    this.nextServersFromGetLocal(); // May need to be after subscribe.. Hot off presses.. 
    this.serversSubs = this.servers$.subscribe((servers:Server[]) =>
        this.servers = servers);
  }


  private nextServersFromGetLocal():void {
    this.storage.get(LoginService.SERVER).
      then( (value:string) =>  {
            this.servers$.next( JSON.parse(value) as Server[] );
                               }
      ).catch( ()           => {
             this.servers$.next( [] as Server[] );
                               }
      );
  }     

  private nextServersFromSetLocal(servers:Server[]): void {
    let data = JSON.stringify(servers);
    this.storage.set(LoginService.SERVER, data);
    this.servers$.next(servers);
  }

  getServers$(): BehaviorSubject<Server[]> {
    return this.servers$;
  }

  addServer(addServer:Server): void {
     // other code too...
     this.servers.push(addServer);
     this.nextServersFromSetLocal(this.servers);
  }

  changeServer(changeServer:Server): void {
    // other code too...
    this.nextServersFromSetLocal(this.servers);
  }

  deleteServer(deleteServer:Server): void {
    // other code too..
    this.nextServersFromSetLocal(this.servers);
  }
}

这种重构具有简化其他代码的额外好处由于异步行为,不必内联复杂的嵌套/重复promise / then / catch代码块,对服务执行CRUD操作。希望这可以帮助你。

This refactoring had the added benefit of simplifying other code that did CRUD operations on the service, by not having to inline complex nested/repeating promise/then/catch blocks of code because of asynchronous behaviour. Hope this helps you.

你可以在我的Ionic应用程序的上下文中了解它是如何工作的 here ,当我发布相关问题时,你可以请参阅屏幕截图

You can sort of get the idea of how this worked within the context of my Ionic app here, as I posted a related question, and you can see the HTML view side of this in the screenshot

这篇关于离子存储“得到”仅在方法内的第二次调用时返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆