【问题标题】:StorageService returning callback Ionic2/Angular2StorageService 返回回调 Ionic2/Angular2
【发布时间】:2017-06-30 21:02:31
【问题描述】:

我对存储的异步调用有很多问题,在我的 console.log 上它显示第一行 50,然后是第 20 行...我想避免这种情况。

我有一项服务,我调用了我的存储,但所有调用都返回一个 Promise 并且在我调用它们的任何地方我都必须执行.then().catch() 所以它给我带来了问题......我怎样才能让方法返回一个回调?所以我可以调用我的方法而不考虑异步?

我的StorageService 的一个例子是

import { Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';

//Storage
import { Storage } from '@ionic/storage';


@Injectable()
export class StorageServiceProvider {

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

    saveUser(user) {
        if (user== null) return;
        var userToSave= { "id": user["id"], "info": user["info"] };
        this.storage.set('userStored', JSON.stringify(userToSave));
    }
    //I'd like to do it like this, but I can't because Asyncronous so I have to do it like this.storage.get('userStored');
    getUserId() {
        this.storage.get('userStored').then((idUser) => {
            return JSON.parse(idUser["id"]);
        })
            .catch((err: any) => {
                console.log("Err");

            });

    }
    //I'm testing this now
    getUserInfo() {
        return this.storage.get("userStored");

    }
    //RestsLocalStorage
    resetLocalStorage() {
        this.storage.clear();
    }

}

例如,我想有一个方法返回给我id 和其他info,但只知道如何获得object...

来自组件的调用是这样的……

this.storageServiceProvider.getUserInfo().then((information) => {
    var infoStored = JSON.parse(information)["info"];
    console.log(infoStored );
    //if..else
  })
    .catch((err: any) => {
      console.log("Error");

    });

 }

在其他方法中,我需要同时调用它们...并且我想避免 2 然后捕获...我想做这样的事情:

let userInfo= this.storageServiceProvider.getUserInfo;
let userId= this.storageServiceProvider.getUserId;

我有一个旧项目 (Ionic1/Angluar1),我做了这样的事情:

angular.module('app.storageServices', [])
.factory ("storageService", ['$localStorage',function ($localStorage) {

    var saveUser = function (user) {      
      if(user==null) return;
      $localStorage.userId=user.id;
      $localStorage.userInfo=user.info;
    };

    var getIdUser = function () {
      if($localStorage.userId!=null){
        return $localStorage.userId;    
      }
      return null;
    };
    var getInfoUser = function () {
      if($localStorage.info!=null){     
        return $localStorage.info;  
      }
      return null;
    };

    return {
        saveUser: saveUser,
        getIdUser: getIdUser,
        getInfoUser: getInfoUser       
    };
}])

而我只是在调用这样的方法:

this.myTestFunction=function(success,error){

    var userId=storageService.getUserId();
    if(userId!=null && userId!=""){
        var userInfo=storageService.getUserInfo();
        //if..else 
    }else{
        console.log("error");           
    }       
}

那么我是否可以拥有类似于我的旧项目的 >=ionic2 和 >=Angular2 的东西?

我错过了什么?

【问题讨论】:

  • 所以您想将您的 promise/observable 调用转换为同步调用?我不认为这是一个好主意,我不会这样做
  • 那么@crash 你能告诉我如何使用 promise/observable 调用获取值吗?
  • 这取决于您想如何使用它,没有真正需要将其转换为可观察的...您可以使用Observable.fromPromise() 来完成它,但它的行为方式与承诺相同,您可以利用可观察对象的所有方法,因此您将拥有很大的灵活性,但无论如何它都是异步的

标签: angular typescript ionic-framework ionic2


【解决方案1】:

使用异步代码时,您无法创建同步调用。异步代码的关键在于您不会立即获得结果,因此您必须等到它可用。没有办法解决这个问题。

在您的示例中,我不明白为什么您有两种不同的获取方法,一种用于userId,另一种用于userInfo。因为这两个值都存储在同一个位置,所以您只需使用getUserInfo(),然后访问idinfo 或任何您需要的属性。

但是假设您的代码只是一个示例,您确实需要多个 get 函数。你有两个选择:

在您的StorageServiceProvider 中,您返回承诺。

getUserId() {
    return this.storage.get('userIdStored');
}

getUserInfo() {
    return this.storage.get("userInfoStored");
}

然后您可以使用Promise.all() 等待所有承诺立即解决。

Promise.all([this.storageServiceProvider.getUserId(), this.storageServiceProvider.getUserInfo()])
.then(values => {
  console.log(values); // [userId, userInfo]
});

另一种选择是使用新的async/await 语法:

async function() {
  let userId = await this.storageServiceProvider.getUserId();
  let userInfo = await this.storageServiceProvider.getUserInfo()
  // Note: This is synchronous, so the 2 Promises are not executed in parallel. Read more here: https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8
}

编辑:

如果您只获取用户 ID,则必须创建自己的承诺并使用您需要的值解决:

getUserId() {
  return new Promise((resolve, reject) => {
    this.storage.get('userInfo')
      .then(user => {
        resolve(user.id);
      })
      .catch(reject);
  });
}

getUserId() 现在将解析一个使用 userId 解析的 Promise,因此您可以像这样使用它:

this.storageServiceProvider.getUserId().then(id => {
  console.log(id); // UserID
})

async myFunction() {
  let userId = await this.storageServiceProvider.getUserId();
  console.log(userId);
}

【讨论】:

  • 让我测试第一个,好不​​好告诉你
  • 它返回给我的是这样的:(2) ["{"id":"0","info":"hellooo"}", undefined] 0 : "{"id":"0","info":"hellooo"}" 1 : undefined
  • 我想在调用 this.storageServiceProvider.getUserId() 时直接获取 id 我的意思是这样做我想获取例如 0,如果我返回 this.storage。获取(“用户信息存储”);它将返回:"{"id":"0","info":"hellooo"}"
  • 我更新了我的答案。就像我之前说的,不可能使这个同步。您唯一可以做的另一件事是将 id 直接存储到 StorageServiceProvider 中的类变量中,然后您可以简单地同步返回该值。但是您必须假设该值尚未初始化。但我肯定会推荐带有承诺的版本,因为它不易出错。
  • 我不能返回一个 int 而不是一个 promise?
猜你喜欢
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 2017-02-16
  • 1970-01-01
  • 2016-11-30
  • 1970-01-01
  • 2017-07-14
相关资源
最近更新 更多