![](/img/trans.png)
[英]Resolving a promise in a service/factory vs in a controller with AngularJS
[英]Resolving a promise in a dependent AngularJS service
我有一個使用存儲API在Chrome擴展程序中運行的簡單AngularJS應用。 對存儲的異步性有疑問; 我已經將存儲抽象為一個“ UserService”,該“ UserService”將數據作為工廠設置並獲取:
app.factory('UserService',
function($q, AppSettings) {
var defaults = {
api: {
token: AppSettings.environments[1].api.token
},
email: ''
};
var service = {
user: {},
save: function() {
chrome.storage.sync.set({'user': angular.toJson(service.user)});
},
restore: function() {
var deferred = $q.defer();
chrome.storage.sync.get('user', function(data) {
if(!data) {
chrome.storage.sync.set({'user': defaults});
service.user = defaults;
} else {
service.user = angular.fromJson(data.user);
}
deferred.resolve(service);
});
return deferred.promise;
}
};
// set the defaults
service.restore().then(function(data) {
console.log(data);
return data;
});
});
上面的console.log()
調用按預期轉儲了數據。 但是,當我將UserService包括在其他工廠中時(我有一個使用用戶特定API令牌的APIService),在以下代碼中,UserService參數被標記為“未定義”:
app.factory('APIService',
function($resource, $http, UserService, AppSettings) {
var token = UserService.user.api.token;
...
});
我確信我在整個應用程序中消費已解決的承諾方面並沒有完全掌握Angular承諾模式。
更新的代碼:
app.factory('UserService',
function($q, AppSettings) {
var defaults = {
api: {
token: AppSettings.environments[1].api.token
},
email: ''
};
var service = {
user: {},
save: function() {
chrome.storage.sync.set({'user': angular.toJson(service.user)});
},
restore: function() {
var deferred = $q.defer();
chrome.storage.sync.get('user', function(data) {
if(!data) {
chrome.storage.sync.set({'user': defaults});
service.user = defaults;
} else {
service.user = angular.fromJson(data.user);
}
deferred.resolve(service.user);
});
return deferred.promise;
}
};
// set the defaults
service.restore().then(function(data) {
console.log(data);
return data;
});
return service;
});
編輯/其他信息:
好吧,近距離接觸。 進行了重構,以便我可以正確地返回對象,但是現在的問題是,當創建APIService
並嘗試使用UserService
對象的屬性時,它們根本不存在,因為它們僅在異步還原方法之后創建解決了。 因此無法訪問UserService.user.api.token
屬性,因為那時該屬性尚不存在,所以問題是,如果該數據不可用,如何在需要的時候在APIService中獲取該數據點? 我試圖避免必須將APIService
的全部內容放入一個假設的新UserService.get()
方法之后觸發的回調中,該方法在對promise進行解析時調用該回調。 任何最終指導表示贊賞。
您不是要從工廠退貨。 因此,當您嘗試注入UserService
參數時,它會給出undefined,因為您尚未從UserService函數返回任何信息。
如果返回service
變量,我想您會得到想要的行為。
您的服務有誤。 請查看我的解決方法:
app.factory('UserService',
function($q, AppSettings) {
var defaults = {
api: {
token: AppSettings.environments[1].api.token
},
email: ''
};
var service = {
user: {},
save: function() {
chrome.storage.sync.set({'user': angular.toJson(service.user)});
},
restore: function() {
var deferred = $q.defer();
chrome.storage.sync.get('user', function(data) {
if(!data) {
chrome.storage.sync.set({'user': defaults});
service.user = defaults;
} else {
service.user = angular.fromJson(data.user);
}
deferred.resolve(service.user); // <--- return the user in here
});
return deferred.promise;
}
};
// set the defaults
service.restore().then(function(data) {
console.log(data);
return data;
});
return service; // <--- return the service to be used injected when injected
});
[編輯]回答您的新問題:不要直接訪問用戶。 在您的服務中創建一個新函數,例如getUser(),它會返回一個承諾。 在該函數中,如果已經檢索過用戶,則返回用戶,否則返回restore()函數:
var service = {
user: null,
getUser: function() {
if (service.user)
{
var deferred = $q.defer();
deferred.resolve(service.user);
return deferred.promise;
}
else
return service.restore();
},
save: function() {
chrome.storage.sync.set({'user': angular.toJson(service.user)});
},
restore: function() {
var deferred = $q.defer();
chrome.storage.sync.get('user', function(data) {
if(!data) {
chrome.storage.sync.set({'user': defaults});
service.user = defaults;
} else {
service.user = angular.fromJson(data.user);
}
deferred.resolve(service.user); // <--- return the user in here
});
return deferred.promise;
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.