2017-06-29 68 views
0

我有很多问题与我的Asyncronous调用存储,在我的console.log它显示第一行50,然后行20 ...我想避免这一点。StorageService返回回调Ionic2/Angular2

我有一个服务,我打电话给我的存储,但所有返回一个承诺,并在任何地方我打电话给他们,我必须做.then().catch()所以它给我的问题...我怎么能做到这一方法返回一个回调?所以我可以打电话给我的方法,不要考虑Asyncronous?

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?

我失踪了什么?

+0

所以你想你的诺言/观察到的调用转换成一个同步?我不认为这是一个好主意,你我不会这样做 – crash

+0

然后@crash你能告诉我如何使用promise/observable调用来获取值吗? – Stuart2041

+0

它取决于你想如何使用它,没有真正的需要将其转换为可观察的......你可以用'Observable.fromPromise()'来实现它,但它的行为方式与承诺相同,你可以利用所有可观察的方法,所以你会有很大的灵活性,但它会异步 – crash

回答

1

使用异步代码时无法创建同步呼叫。异步代码的关键是你没有立即得到结果,所以你必须等到它可用。这是没有办法的。

在你的例子中,我不明白你为什么有两种不同的get方法,一种是userId,另一种是userInfo。因为两个值都存储在同一个地方,您可以使用getUserInfo(),然后访问idinfo或您需要的任何属性。

但让我们说你的代码只是一个例子,你真的需要多个获取函数。您有2个选项:

在您的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()现在解决与用户id解决了一个承诺,所以你可以使用它像:

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

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

让我测试第一个,我会让你知道,如果它没关系 – Stuart2041

+0

它回到我这样的东西:“(”)“”{“id”:“0”,“info”:“hellooo”}“,undefined] : ”{“id”:“0”,“info”:“hellooo” }“: undefined' – Stuart2041

+0

我想在调用this.storageServiceProvider.getUserId()时直接得到id。我的意思是这样做我想得到例如0,如果我确实返回这个。 storage.get(“userInfoSto红”);它会返回这个:“{”id“:”0“,”info“:”hellooo“}” – Stuart2041