2017-06-29 82 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