![](/img/trans.png)
[英]How to return a resolved promise from an AngularJS Service using $q?
[英]Immediately return a resolved promise using AngularJS
我試圖了解JavaScript中的承諾(特別是AngularJS)。
我在服務中有一個函數,我們稱之為fooService
,它檢查我們是否加載了一些數據。 如果有,我只想讓它返回,如果我們沒有,我們需要加載數據並返回一個承諾:
this.update = function(data_loaded) {
if (data_loaded) return; // We've loaded the data, no need to update
var promise = Restangular.all('someBase').customGet('foo/bar').then(function(data) {
// Do something with the data here
}
return promise;
}
我有另一個函數然后調用fooService
的update
函數, fooService
所示:
fooService.update(data_loaded).then(function() {
// Do something here when update is finished
})
我的問題是如果我們不需要在update
函數中加載數據,則不返回promise,因此在我的其他函數中不會調用.then()
。 該方法應該在這里 - 基本上我想立即從update()
函數返回一個已解決的promise,如果我們不需要從Restangular調用中獲取數據?
由於您的承諾使用與JavaScript本機相同的語法,您可以使用並返回已經解析的JavaScript承諾: Promise.resolve()
return(Promise.resolve("MyReturnValue"));
當前接受的答案過於復雜,並且濫用延遲的反模式 。 這是一個更簡單的方法:
this.update = function(data_loaded) {
if (data_loaded) return $q.when(data); // We've loaded the data, no need to update
return Restangular.all('someBase').customGet('foo/bar')
.then(function(data) {
// Do something with the data here
});
};
或者,甚至更進一步:
this._updatep = null;
this.update = function(data_loaded) { // cached
this._updatep = this._updatep || Restangular.all('someBase') // process in
.customGet('foo/bar'); //.then(..
return this._updatep;
};
AngularJS的$ q服務將在這里為您提供幫助。 這很像Kris Kowal的Q promise圖書館。
當您有一個可以返回promise或值的異步方法時,請使用$ q.when方法。 它將傳遞給它,無論是承諾還是價值,並根據傳遞的承諾創建將被解決/拒絕的承諾,或者如果傳遞值,則解決。
$q.when( fooService.update(data_loaded) ).then(function(data){
//data will either be the data returned or the data
//passed through from the promise
})
然后在您的更新函數中返回數據而不是僅返回
if (data_loaded) return data_loaded;
與Elo的答案類似,您可以使用async / await語法返回已解析的promise:
this.update = async (data_loaded) => {
if (data_loaded)
return await null; // Instead of null, you could also return something else
// like a string "Resolved" or an object { status: 200 }
else
return await OtherPromise();
}
您可以像這樣使用$q.defer()
:
this.update = function (data_loaded) {
var deferred = $q.defer();
if (data_loaded) {
deferred.resolve(null); // put something that your callback will know the data is loaded or just put your loaded data here.
} else {
Restangular.all('someBase').customGet('foo/bar').then(function(data) {
// Do something here when update is finished
deferred.resolve(data);
}
}
return deferred.promise;
};
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.