Armazenando em cache um object de promise no serviço AngularJS

Eu quero implementar um carregamento dynamic de um recurso estático no AngularJS usando Promises. O problema: eu tenho alguns componentes na página que podem (ou não, depende de quais são exibidos, assim dynamics) precisam obter um recurso estático do servidor. Uma vez carregado, ele pode ser armazenado em cache durante toda a vida útil da aplicação.

Eu implementei esse mecanismo, mas sou novo no Angular e no Promises, e quero ter certeza de que essa é uma solução / abordagem correta.

var data = null; var deferredLoadData = null; function loadDataPromise() { if (deferredLoadData !== null) return deferredLoadData.promise; deferredLoadData = $q.defer(); $http.get("data.json").then(function (res) { data = res.data; return deferredLoadData.resolve(); }, function (res) { return deferredLoadData.reject(); }); return deferredLoadData.promise; } 

Portanto, apenas uma solicitação é feita e todas as próximas chamadas para loadDataPromise () retornam a primeira promise. Parece trabalhar para pedido que no progresso ou um que já terminou há algum tempo atrás.

Mas é uma boa solução armazenar em cache o Promises?

    É este o caminho certo?

    Sim. O uso de memoisação em funções que retornam promete uma técnica comum para evitar a execução repetida de tarefas assíncronas (e geralmente caras). A promise torna o armazenamento em cache fácil porque não é necessário distinguir entre as operações em andamento e as concluídas, ambas são representadas como (a mesma) promise para o valor do resultado.

    Esta é a solução correta?

    Não. Essa variável de data global e a resolução com undefined não é como as promises devem funcionar. Em vez disso, cumpra a promise com os data do resultado! Também facilita muito a codificação:

     var dataPromise = null; function getData() { if (dataPromise == null) dataPromise = $http.get("data.json").then(function (res) { return res.data; }); return dataPromise; } 

    Então, em vez de loadDataPromise().then(function() { /* use global */ data }) é simplesmente getData().then(function(data) { … }) .

    Para melhorar ainda mais o padrão, talvez você queira ocultar dataPromise em um escopo de fechamento e observe que precisará de uma pesquisa para promises diferentes quando getData um parâmetro (como o URL).

    Para esta tarefa, criei o serviço chamado defer-cache-service, que remove todo esse código da placa de caldeira. Escreveu em Typescript, mas você pode pegar o arquivo js compilado. Código-fonte do Github.

    Exemplo:

     function loadCached() { return deferCacheService.getDeferred('cacke.key1', function () { return $http.get("data.json"); }); } 

    e consumir

     loadCached().then(function(data) { //... }); 

    Uma coisa importante é notar que se vamos dizer que duas ou mais partes chamando o mesmo loadDataPromise e ao mesmo tempo, você deve adicionar essa verificação

     if (defer && defer.promise.$$state.status === 0) { return defer.promise; } 

    caso contrário, você fará chamadas duplicadas para o back-end.