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

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

问题描述

我在使用 Ionic Storage 时遇到了一个非常奇怪的问题.我有一个方法可以从存储中读取一个值并返回一个包含与该对象对应的对象的承诺:

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

这种重构的额外好处是简化了对服务执行 CRUD 操作的其他代码,因为异步行为不必内联复杂的嵌套/重复 promise/then/catch 代码块.希望这对您有所帮助.

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,因为我发布了一个相关的问题,您可以在屏幕截图中看到 HTML 视图的一面

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

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

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