簡體   English   中英

在依賴的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM