2017-01-24 4 views
2

У меня есть следующий код кода, в котором вызов обновления выполняется каждый раз, когда пользователь обновляет данные в представлении.Второй вызов обещания выполняется перед возвращением обещаний - Угловой Javascript

// FACTORY SERVICE CODE 
.factory('updateService', ['$http', '$q', function($http, $q){ 
    var df = $q.defer(); 
    var updateData = function(uriName, dataObj){ 
     $http({ 
      method: 'PUT', 
      data: dataObj, 
      url: uriName 
      }).then(function successCallback(response) { 
       console.log('from put'); 
       console.log(response.data); 
       df.resolve(response.data); 
      }, function errorCallback(response) { 
       console.log('Error', response.data); 
       df.reject(response.data); 
     }); 
     return df.promise; 
    } 
    return {updateData:updateData}; 
}]) 

// CONTROLLER CODE 
.controller('MainCtrl', ['$scope','updateService', function($scope, updateService) { 
    $scope.saveToServer = function(){ 
     var tmpObj = {data: $scope.dataOne, anotherData: $scope.dataTwo}; 
     myService.updateData(uriName, tmpObj).then(function(resolved) { 
      console.log('CONTROLLER'); 
      $scope.myData = resolved; 
      console.log($scope.myData); 
      console.log('end'); 
     }, function(rejected){ 
      console.log('put rejected'); 
     }); 
    }); 
    $scope.btnUpdateClick = function(){ 
     $scope.saveToServer(); 
    }; 
}]); 

ПРОБЛЕМА: Когда пользователь делает запрос на обновление в первый раз, код работает, как ожидалось. Но когда пользователь обновляется после этого, код «разрешенного обещания» (в контроллере) выполняется FIRST, а затем выполняется код $ http (в службе).

Пример вывода btnUpdateClick из ДВАЖДЫ с достаточным интервалом в промежутке между:

from put 
Array [ Object, Object] 
CONTROLLER 
Array [ Object, Object] 
end 
CONTROLLER 
Array [ Object, Object] 
end 
from put 
Array [ Object, Object] 

ВОПРОС: Просьба указать мне, где я делаю ошибку?

Является ли проблема из-за запроса PUT?

или можно исправить очередь выполнения, как ожидалось, через $ apply или что-то в этом роде?

+0

'вар DF = $ д.defer(); 'переместите этот код внутри' updateData' функции , и еще одно предложение заключается в том, почему вы создаете отдельное обещание для вызова $ http. Просто верните обещание $ http. –

+0

@pragaas было бы лучше принять ответ после продолжения :) –

+0

@ARUN - правильно указал. – Mikki

ответ

1

Начало Обещание каждый раз при вызове функции, как показано ниже:

.factory('updateService', ['$http', '$q', function($http, $q){ 

    var updateData = function(uriName, dataObj){ 
     var df = $q.defer(); //Changes here 
     $http({ 
      method: 'PUT', 
      data: dataObj, 
      url: uriName 
      }).then(function successCallback(response) { 
       console.log('from put'); 
       console.log(response.data); 
       df.resolve(response.data); 
      }, function errorCallback(response) { 
       console.log('Error', response.data); 
       df.reject(response.data); 
     }); 
     return df.promise; 
    } 
    return {updateData:updateData}; 
}]) 

Таким образом, вы создаете новое обещание при каждом вызове функции.

0

Изменить код:

// FACTORY SERVICE CODE 
.factory('updateService', ['$http', '$q', function($http, $q){ 
    var updateData = function(uriName, dataObj){ 
     var df = $q.defer(); 
     $http({ 
      method: 'PUT', 
      data: dataObj, 
      url: uriName 
      }).then(function successCallback(response) { 
       console.log('from put'); 
       console.log(response.data); 
       df.resolve(response.data); 
      }, function errorCallback(response) { 
       console.log('Error', response.data); 
       df.reject(response.data); 
     }); 
     return df.promise; 
    } 
    return {updateData:updateData}; 
}]) 

// CONTROLLER CODE 
.controller('MainCtrl', ['$scope','updateService', function($scope, updateService) { 
    $scope.saveToServer = function(){ 
     var tmpObj = {data: $scope.dataOne, anotherData: $scope.dataTwo}; 
     myService.updateData(uriName, tmpObj).then(function(resolved) { 
      console.log('CONTROLLER'); 
      $scope.myData = resolved; 
      console.log($scope.myData); 
      console.log('end'); 
     }, function(rejected){ 
      console.log('put rejected'); 
     }); 
    }); 
    $scope.btnUpdateClick = function(){ 
     $scope.saveToServer(); 
    }; 
}]); 

В вашем старом коде, создавал перенести объект только один раз, так что было решено/отклоненных только один раз. Но вам нужно возвращать обещание каждый раз и разрешать/отклонять его каждый раз.

+0

«измените свой код на» - почему? что случилось? –

+3

Кодовые ответы не очень полезны. Объясните, что именно нужно исправлять. – Pointy

+0

Имейте терпение @Pointy –

3

Здесь нет необходимости создавать индивидуальные обещания, хотя это считается плохой практикой.

Является ли проблема из-за запроса PUT?

Это не проблема, связанная с запросом PUT. Ваш завод использует общий объект deferred и тот же был возвращен из метода. Как только объект promise будет разрешен, он всегда будет в разрешенном состоянии.


Скорее я хотел бы предложить вам использовать $http.put обещание и сделать код меньше, чем то, что вы были раньше.

var updateData = function(uriName, dataObj){ 
    return $http.put(uriName,dataObj) 
} 
+0

Ваш подход кодирования абсолютно правильный. Но поскольку мой вопрос касался исправления ошибки, которую я имел в своем коде, я хотел бы, чтобы другое решение было ответом, только для записи. Хорошая работа! – Mikki

4

Вы используете "explicit promise creation antipattern" здесь, и на вершине, что, пытаясь разделить один отложенный объект среди всех вызовов службы.

Просто избавиться от отсроченных и воспользоваться СЦЕПЛЕНИЕМ свойств обещают и все будет хорошо:

.factory('updateService', ['$http', '$q', function($http, $q){ 
    var updateData = function(uriName, dataObj){ 
     return $http({ 
      method: 'PUT', 
      data: dataObj, 
      url: uriName 
     }) 
     .then(function successCallback(response) { 
      console.log('from put'); 
      console.log(response.data); 
      return response.data; 
     }) 
     .catch(function errorCallback(response) { 
      console.log('Error', response.data); 
      throw response.data; 
     }); 
    }; 

    return {updateData:updateData}; 
}]); 
+0

Ваш подход к кодированию абсолютно правильный. Но поскольку мой вопрос касался исправления ошибки, которую я имел в своем коде, я хотел бы получить это решение в качестве ответа, только для записи. Хорошая работа! – Mikki

+0

так очень, много абсолютно –

Смежные вопросы