2016-04-14 5 views
0

У меня есть следующий код в контроллере javascript. Функции работают, когда вызываются независимо и асинхронно из представления. Однако я хочу, чтобы назвать их синхронно на странице загрузки, как возвращаемое значение из первой функции используется в вызове для второй функцииУгловое обещание не работает синхронно

$scope.function1= function() { 
    $http({ 
     url: '/Class/method1/', 
     method: 'GET' 
    }).success(function (data) { 
     $scope.mygrid= data.data; 
     $scope.myvalue= $scope.mygrid[0]; 
    }); 
}; 

$scope.function2= function() { 
    $http({ 
     url: '/class/method2/', 
     method: 'POST', 
     params: { myValue: $scope.myvalue } 
    }).success(function (data) { 
     $scope.myValue2 = data.data; 
    }); 
}; 

var initialize = function() { 
    var defer = $q.defer(); 
    defer.promise 
     .then(function() { 
      $scope.function1(); 
     }) 
     .then(function() { 
      $scope.function2(); 
     }) 
defer.resolve(); 
    }; 
initialize(); 

На второй вызов $ scope.myvalue равна нулю. Данные были возвращены из функции 1, поэтому единственное, что я могу думать, это то, что function2 вызывается слишком рано. Любые указатели? :-)

+1

Обещание никогда не синхронно. [Обещания не волшебство] (http://stackoverflow.com/a/22562045/1048572). Вам нужно «вернуть» их из обратных вызовов «then» и из вашей области «functionN's», иначе они не смогут знать, что вы хотите что-то ждать. – Bergi

+0

, если вы хотите, чтобы функция2 запускалась после функции1, она должна быть вызвана успешным выполнением функции 1 или где-то еще, после проверки функции1 возвращены ожидаемые данные. –

ответ

1

Обещание в initialize выполняется синхронно. Пока $http запросов нет. Это приводит к вызову $scope.function2, не дожидаясь обещания в $scope.function1.

Это должно быть

$scope.function1= function() { 
    return $http... 
}; 

$scope.function2= function() { 
    return $http... 
}; 

В этом случае отсроченного обещания is antipattern и initialize должен быть краткими, как:

var initialize = function() { 
    return $scope.function1().then(function() { 
      return $scope.function2(); 
    }) 
    }; 
-1
$http({ 
     url: 'url', 
     method: 'GET' 
    }) 

это тоже одно обещание, поэтому оно будет работать как асинхронный.

$scope.function1= function() {//3rd step 
    $http({ 
     url: '/Class/method1/', 
     method: 'GET' 
    }).success(function (data) { 
     $scope.mygrid= data.data; //this run as asyn after response recived 
     $scope.myvalue= $scope.mygrid[0]; 
    }); 
}; 

$scope.function2= function() { //5th step 
    $http({ 
     url: '/class/method2/', 
     method: 'POST', 
     params: { myValue: $scope.myvalue } 
    }).success(function (data) { 
     $scope.myValue2 = data.data; //this run as asyn after response recived 
    }); 
}; 

var initialize = function() { 
    var defer = $q.defer(); 
    defer.promise 
     .then(function() { 
      $scope.function1(); //2nd step 
     }) 
     .then(function() { 
      $scope.function2(); //4th step 
     }) 
defer.resolve(); //1st step 
    }; 
initialize(); 
Смежные вопросы