Szukaj…


Używanie $ q.all do obsługi wielu obietnic

Możesz użyć funkcji $q.all aby wywołać metodę .then po pomyślnym rozwiązaniu tablicy obietnic i pobraniu danych, które zostały rozwiązane.

Przykład:

JS:

 $scope.data = []

 $q.all([
    $http.get("data.json"),
    $http.get("more-data.json"),
    ]).then(function(responses) {
      $scope.data = responses.map((resp) => resp.data);
    });

Powyższy kod działa $http.get 2 razy do danych w plikach lokalnych json, gdy zarówno get metoda zakończyć się rozwiązać związane z nimi obietnice, gdy wszystkie obietnice w tablicy są rozwiązany, .then rozpoczyna metoda zarówno dane obietnice wewnątrz responses argument tablicowy.

Dane są następnie mapowane, aby mogły zostać pokazane w szablonie, który możemy następnie pokazać

HTML:

<ul>
   <li ng-repeat="d in data">
      <ul>
         <li ng-repeat="item in d">{{item.name}}: {{item.occupation}}</li>
      </ul>
   </li>
</ul>

JSON:

[{
  "name": "alice",
  "occupation": "manager"
}, {
  "name": "bob",
  "occupation": "developer"
}]

Używanie konstruktora $ q do tworzenia obietnic

Funkcja konstruktora $q służy do tworzenia obietnic z asynchronicznych interfejsów API, które używają wywołań zwrotnych do zwracania wyników.

$ q (funkcja (rozwiązuje, odrzuca) {...})

Funkcja konstruktora odbiera funkcję, która jest wywoływana z dwoma argumentami: resolve i reject które są funkcjami używanymi do rozwiązania lub odrzucenia obietnicy.

Przykład 1:

function $timeout(fn, delay) {
    return = $q(function(resolve, reject) {
         setTimeout(function() {
              try {
                 let r = fn();
                 resolve(r);
              } 
              catch (e) {
                 reject(e);
              }
         }, delay);
     };
}
    

Powyższy przykład tworzy obietnicę z interfejsu API WindowTimers.setTimeout . Struktura AngularJS zapewnia bardziej rozbudowaną wersję tej funkcji. Informacje na temat użytkowania można znaleźć w dokumentacji interfejsu API usługi limitu czasu usługi AngularJS $ .

Przykład 2:

$scope.divide = function(a, b) {
    return $q(function(resolve, reject) {
      if (b===0) {
        return reject("Cannot devide by 0")
      } else {
        return resolve(a/b);
      }
    });
}

Powyższy kod pokazuje obiecaną funkcję podziału, zwróci obietnicę z wynikiem lub odrzuci powód, jeśli obliczenie jest niemożliwe.

Można połączyć i wykorzystać .then

$scope.divide(7, 2).then(function(result) {
    // will return 3.5
}, function(err) {
    // will not run
})

$scope.divide(2, 0).then(function(result) {
    // will not run as the calculation will fail on a divide by 0
}, function(err) {
    // will return the error string.
})

Odroczenie operacji za pomocą $ q.defer

Możemy użyć $q aby odroczyć operacje na przyszłość, mając obecnie oczekujący obiekt przyrzeczenia, używając $q.defer tworzymy obietnicę, która zostanie rozwiązana lub odrzucona w przyszłości.

Ta metoda nie jest równoważna z użyciem konstruktora $q , ponieważ używamy $q.defer aby obiecać istniejącą procedurę, która może, ale nie musi, w ogóle (lub kiedykolwiek zwróciła) obietnicę.

Przykład:

var runAnimation = function(animation, duration) {
    var deferred = $q.defer();
    try {
        ...
        // run some animation for a given duration
        deferred.resolve("done");
    } catch (err) {
        // in case of error we would want to run the error hander of .then
        deferred.reject(err);
    }
    return deferred.promise;
}

// and then
runAnimation.then(function(status) {}, function(error) {})

  1. Pamiętaj, aby zawsze zwracać obiekt deferred.promise lub ryzykować błąd podczas wywoływania. .then

  2. Upewnij się, że zawsze rozwiązujesz lub odrzucasz odroczony obiekt, w przeciwnym .then może nie działać i ryzykujesz wyciekiem pamięci

Korzystanie z obietnic kątowych w usłudze $ q

$q jest wbudowaną usługą, która pomaga w wykonywaniu funkcji asynchronicznych i używaniu ich wartości zwracanych (lub wyjątków) po zakończeniu przetwarzania.

$q jest zintegrowany z mechanizmem obserwacji modelu $rootScope.Scope , co oznacza szybsze propagowanie rozdzielczości lub odrzucania do twoich modeli i unikanie niepotrzebnych odświeżeń przeglądarki, co spowodowałoby migotanie interfejsu użytkownika.

W naszym przykładzie nazywamy naszą fabrykę getMyData , która zwraca obiekt obietnicy. Jeśli obiekt zostanie resolved , zwraca liczbę losową. Jeśli zostanie rejected , zwraca odrzucenie z komunikatem o błędzie po 2 sekundach.

W fabryce Angular

function getMyData($timeout, $q) {
  return function() {
    // simulated async function
    var promise = $timeout(function() {
      if(Math.round(Math.random())) {
        return 'data received!'
      } else {
        return $q.reject('oh no an error! try again')
      }
    }, 2000);
    return promise;
  }
}

Korzystanie z obietnic na telefon

angular.module('app', [])
.factory('getMyData', getMyData)
.run(function(getData) {
  var promise = getData()
    .then(function(string) {
      console.log(string)
    }, function(error) {
      console.error(error)
    })
    .finally(function() {
      console.log('Finished at:', new Date())
    })
})

Aby użyć obietnic, wstrzyknij $q jako zależność. Tutaj wstrzyknęliśmy $q do fabryki getMyData .

var defer = $q.defer();

Nowa instancja odroczenia jest budowana przez wywołanie $q.defer()

Odroczony obiekt to po prostu obiekt, który ujawnia obietnicę, a także powiązane metody jej rozwiązania. Jest skonstruowany przy użyciu funkcji $q.deferred() i udostępnia trzy główne metody: $q.deferred() resolve() , reject() i notify() .

  • resolve(value) - rozwiązuje obietnicę pochodną o wartości.
  • reject(reason) - odrzuca obietnicę pochodną wraz z powodem.
  • notify(value) - informuje o stanie realizacji promesy. Można to wywołać wiele razy, zanim obietnica zostanie rozwiązana lub odrzucona.

Nieruchomości

Powiązany obiekt przyrzeczenia jest dostępny za pośrednictwem właściwości przyrzeczenia. promise - {Obietnica} - obiekt obietnicy związany z tym odroczeniem.

Nowa instancja obietnicy jest tworzona, gdy tworzona jest odroczona instancja, i można ją odzyskać, wywołując deferred.promise .

Celem przedmiotu promise jest umożliwienie zainteresowanym stronom dostępu do wyniku odroczonego zadania po jego zakończeniu.

Metody obietnicy -

  • then(successCallback, [errorCallback], [notifyCallback]) - Niezależnie od tego, kiedy obietnica została lub zostanie rozwiązana lub odrzucona, wówczas asynchronicznie wywołuje jedno z callbacków powodzenia lub błędu, gdy tylko wynik będzie dostępny. Wywołania zwrotne są wywoływane za pomocą jednego argumentu: wyniku lub powodu odrzucenia. Ponadto powiadomienie zwrotne może być wywoływane zero lub więcej razy, aby zapewnić wskazanie postępu, zanim obietnica zostanie rozpatrzona lub odrzucona.

  • catch(errorCallback) - skrót dla promise.then (null, errorCallback)

  • finally(callback, notifyCallback) - pozwala zaobserwować spełnienie lub odrzucenie obietnicy, ale zrobić to bez zmiany ostatecznej wartości.

Jedną z najpotężniejszych cech obietnic jest możliwość ich połączenia. Umożliwia to przepływ danych przez łańcuch oraz manipulowanie i mutowanie na każdym etapie. Pokazano to na następującym przykładzie:

Przykład 1:

// Creates a promise that when resolved, returns 4.
function getNumbers() {

  var promise = $timeout(function() {
    return 4;
  }, 1000);
  
  return promise;
}

// Resolve getNumbers() and chain subsequent then() calls to decrement
// initial number from 4 to 0 and then output a string.
getNumbers()
  .then(function(num) {
      // 4
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 3
      console.log(num);
      return --num;
  })
   .then(function (num) {
      // 2
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 1
      console.log(num);
      return --num;
  })
  .then(function (num) {
      // 0
      console.log(num);
      return 'And we are done!';
  })
  .then(function (text) {
      // "And we are done!"
      console.log(text);        
  });

Zawiń prostą wartość w obietnicę za pomocą $ q.when ()

Jeśli wszystko, czego potrzebujesz, to zawrzeć wartość w obietnicy, nie musisz używać długiej składni, jak tutaj:

//OVERLY VERBOSE
var defer;
defer = $q.defer();
defer.resolve(['one', 'two']);
return defer.promise;

W takim przypadku możesz po prostu napisać:

//BETTER
return $q.when(['one', 'two']);

$ q.when i jego alias $ q.resolve

Zawija obiekt, który może być wartością lub obietnicą (innej firmy), wówczas w obietnicę $ q. Jest to przydatne, gdy masz do czynienia z przedmiotem, który może, ale nie musi być obietnicą, lub jeśli obietnica pochodzi ze źródła, któremu nie można ufać.

- AngularJS $ q Dokumentacja interfejsu API usługi - $ q. Kiedy


Wraz z wydaniem AngularJS v1.4.1

Możesz także użyć resolve aliasu zgodnego z ES6

//ABSOLUTELY THE SAME AS when
return $q.resolve(['one', 'two'])

Unikaj odroczonego anty-wzoru $ q

Unikaj tego Anti-Pattern

var myDeferred = $q.defer();

$http(config).then(function(res) {  
   myDeferred.resolve(res);
}, function(error) {
   myDeferred.reject(error);
});

return myDeferred.promise;

Nie trzeba $q.defer obietnicy za pomocą $q.defer ponieważ usługa $ http już zwraca obietnicę.

//INSTEAD
return $http(config);

Po prostu zwróć obietnicę utworzoną przez usługę $ http.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow