2016-04-04 2 views
3

Я пытаюсь выполнить функцию, которая не найдена, если я не сохранить ссылку на функцию в отдельной переменной:объем «этого» в асинхронном функции ионного углового приложения

function updateCheck() { 
      if (this.isNewVersionNeeded()) { 
       var buildFunc = this.buildObject(); 
       this.updateBiography().then(function(){ 
        buildFunc(); 
       }) 
      } 
     }; 

Функция buildObject выполняется, только если я сохраню ее перед выполнением this.updateBiography (асинхронная функция) и выполнит ее через переменную, которую я сохранил в (buildFunc). Ниже не работает:

  function updateCheck() { 
       if (this.isNewVersionNeeded()) { 
        this.updateBiography().then(function(){ 
         this.buildObject(); 
        }) 
       } 
      }; 

Выставляет все функции с помощью объекта службы:

var service = { 
      all: all, 
      updateBiography: updateBiography, 
      get: get, 
      updateCheck: updateCheck, 
      isNewVersionNeeded:isNewVersionNeeded, 
      buildObject:buildObject 
     }; 
     return service; 

Когда я вхожу в «этот» объект в то время как Im непосредственно перед выполнением buildFunc, он записывает окно/глобальный охват. Почему это и как мне с этим бороться? Я не хочу сохранять все мои асинхронные методы в отдельной переменной только для их запоминания. Как мне решить эту проблему и почему она не работает?

Весь сервис:

(function() { 
    angular 
     .module('biography.services', []) 
     .factory('Biography', Biography); 

    Biography.$inject = ['$http']; 

    function Biography($http) { 

     var biographyObject = { } ; 

     var service = { 
      all: all, 
      updateBiography: updateBiography, 
      get: get, 
      updateCheck: updateCheck, 
      isNewVersionNeeded:isNewVersionNeeded, 
      buildObject:buildObject 
     }; 
     return service; 

     var self = this; 
     function updateCheck() { 
      if (this.isNewVersionNeeded()) { 
       this.updateBiography().then(function(){ 
        self.buildObject(); 
       }) 
      } 
     }; 

     function updateBiography() { 
      return $http.get("Apicall adress") 
         .then(function (resp) { 
          window.localStorage.setItem('biography', resp.data); 
          window.localStorage.setItem('biographyTimeStamp', Date.now()); 
         }, function (err) { 
          console.log('ERR', err); 
         }); 
     } 

     function all() {  
      return biographyObject; 
     } 

     function get(name) { 
      var biography = biographyObject; 
      for (var i = 0; i < biography.length; i++) { 
       if (biography[i].name === name) { 
        return biography[i]; 
       } 
      } 
      return null; 
     } 


     function buildObject() { 
      var temp = JSON.parse(window.localStorage.getItem('biography')); 
      biographyObject = temp; 
     }; 

     function isNewVersionNeeded() { 
      prevTimeStamp = window.localStorage.getItem('biographyTimeStamp'); 
      var timeDifference = (Date.now() - prevTimeStamp); 
      timeDifference = 700000; 
      if (timeDifference < 600000) { 
       return false; 
      } 
      else { 
       return true; 
      } 
     } 
    } 
})(); 

ответ

1

Контекст (отличный от области действия) анонимной функции this определяется, когда он вызывается, позднее.

Простое правило - все, что находится слева от точки, например myObj.doSomething() позволяет doSomething получить доступ myObj в this.

function updateCheck() { 
    if (this.isNewVersionNeeded()) { 
     this.updateBiography().then(function() { 

// whichever object has this anonymous function defined/invoked on it will become "this" 

      this.buildObject(); 
     }) 
    } 
}; 

Поскольку вы просто проездом вашу ссылку на функцию, вы можете просто использовать этот

function updateCheck() { 
    if (this.isNewVersionNeeded()) { 
     this.updateBiography().then(this.buildObject); 
    } 
}; 

и если this.buildObject зависит от контекста (использует this ключевое слово внутренне), то могут использоваться

function updateCheck() { 
    if (this.isNewVersionNeeded()) { 
     this.updateBiography().then(this.buildObject.bind(this)); 
    } 
}; 

this по любому контексту (объекту), на который вызывается функция, и кажется, что анонимная функция или функция, не ссылающаяся на объект по умолчанию, имеет контекст window. функция bind заменяет все экземпляры this с фактической ссылкой на объект, так что больше не многоцелевой


же функция вызывается в различных контекстах (на разных объектах)

var obj = { 
    a: function() { 
     console.log(this); 
    } 
}; 
var aReference = obj.a; 
aReference(); // logs window, because it's the default "this" 
obj.a(); // logs obj 
1

Причина здесь 'это' относится к обратному вызову function.You не может получить доступ к 'это' внутри callback.Hence решение,

function Biography($http) { 
     var self = this; 

     function updateCheck() { 
       if (this.isNewVersionNeeded()) { 
        this.updateBiography().then(function(){ 
         self.buildObject(); 
        }) 
       } 
      }; 

Использования Синтаксис ES6:

function updateCheck() { 
        if (this.isNewVersionNeeded()) { 
         this.updateBiography().then(()=>{ 
          this.buildObject(); 
         }) 
        } 
       }; 
+1

Спасибо , решение ES6 работает. Другой нет (я уже пробовал). Я думаю, что это не сработает, потому что в тот момент, когда я делаю var self = this, он возвращает undefined.Так где же в коде я должен это поставить? (отредактировано, чтобы показать весь сервис) – Kai

+0

Поместить его внутри функции Biography() {var self = this} – Ved

+0

Фактически, 'this' зависит от того, где определена анонимная функция и какой путь она вызывается, если контекст явно не указан установить с помощью 'call/bind/apply' – neaumusic