Поиск…


Использование $ q.all для обработки нескольких обещаний

Вы можете использовать функцию $q.all для вызова метода .then после успешного решения массива обещаний и получения данных, с которыми они разрешили.

Пример:

JS:

 $scope.data = []

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

Вышеприведенный код запускает $http.get 2 раза для данных в локальных json-файлах, когда оба метода get завершают, они разрешают связанные с ними обещания, когда все обещания в массиве разрешаются, метод .then начинается с обеим обеим данным в responses аргумент массива.

Затем данные отображаются таким образом, чтобы их можно было отобразить на шаблоне, затем мы можем показать

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"
}]

Использование конструктора $ q для создания обещаний

Функция конструктора $q используется для создания обещаний от асинхронных API, которые используют обратные вызовы для возврата результатов.

$ q (функция (разрешение, отклонение) {...})

Функция-конструктор получает функцию, которая вызывается с двумя аргументами, resolve и reject которые являются функциями, которые используются для разрешения или отклонения обещания.

Пример 1:

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

В приведенном выше примере создается обещание API WindowTimers.setTimeout . Рамка AngularJS обеспечивает более сложную версию этой функции. Для использования см. Справочную информацию об API-интерфейсе AngularJS $ .

Пример 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);
      }
    });
}

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

Затем вы можете позвонить и использовать. .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.
})

Операции отсрочки с использованием $ q.defer

Мы можем использовать $q для отсрочки операций в будущем, имея в настоящее время ожидающий объект обещания, используя $q.defer мы создаем обещание, которое будет либо разрешаться, либо отклоняться в будущем.

Этот метод не эквивалентен использованию конструктора $q , так как мы используем $q.defer чтобы обещать существующую процедуру, которая может или не может возвращать (или когда-либо возвращал) обещание вообще.

Пример:

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. Убедитесь, что вы всегда возвращаете объект deferred.promise Или можете .then при вызове. .then

  2. Убедитесь , что вы всегда разрешить или отклонить отложенный объект или .then не может работать , и вы рискуете утечку памяти

Использование угловых обещаний с помощью услуги $ q

$q - это встроенный сервис, который помогает выполнять асинхронные функции и использовать их возвращаемые значения (или исключение), когда они закончены с обработкой.

$q интегрируется с механизмом наблюдения за моделью $rootScope.Scope , что означает более быстрое распространение разрешения или отклонения в ваших моделях и исключение ненужных переходов браузера, что приведет к мерцанию пользовательского интерфейса.

В нашем примере мы называем наш завод getMyData , который возвращает объект обещания. Если объект resolved , он возвращает случайное число. Если он rejected , он возвращает отказ с сообщением об ошибке через 2 секунды.

В Угловом заводе

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;
  }
}

Использование обещаний по вызову

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())
    })
})

Чтобы использовать обещания, введите $q качестве зависимости. Здесь мы вводили $q в фабрику getMyData .

var defer = $q.defer();

Новый экземпляр отложенных построен путем вызова $q.defer()

Отложенный объект - это просто объект, который предоставляет обещание, а также связанные с ним методы для решения этого обещания. Он построен с использованием функции $q.deferred() и предоставляет три основных метода: resolve() , reject() и notify() .

  • resolve(value) - разрешает производное обещание со значением.
  • reject(reason) - отклоняет полученное обещание по причине.
  • notify(value) - предоставляет обновления статуса выполнения обещания. Это можно назвать несколько раз до того, как обещание будет разрешено или отклонено.

свойства

Связанный объект обещания доступен через свойство prom. promise - {Обещание} - объект обещания, связанный с этим отсроченным.

Новый экземпляр обещания создается, когда созданный отложенный экземпляр создается и может быть получен путем вызова deferred.promise .

Цель объекта promise - предоставить заинтересованным сторонам возможность получить доступ к результатам отложенной задачи, когда она будет завершена.

Методы обещания -

  • then(successCallback, [errorCallback], [notifyCallback]) Независимо от того, когда обещание было или будет разрешено или отклонено, он вызывает асинхронный вызов одного из успешных или ошибочных обратных вызовов, как только результат будет доступен. Обратные вызовы вызываются с помощью одного аргумента: причина или отклонение. Кроме того, обратный вызов уведомления может быть вызван ноль или более раз, чтобы обеспечить индикацию выполнения, прежде чем обещание будет разрешено или отклонено.

  • catch(errorCallback) - сокращенное catch(errorCallback) для обещания. then (null, errorCallback)

  • finally(callback, notifyCallback) - позволяет вам наблюдать за выполнением или отказом от обещания, но делать это без изменения окончательного значения.

Одной из самых мощных возможностей обещаний является способность объединить их вместе. Это позволяет данным проходить через цепочку и манипулировать и мутировать на каждом шаге. Это продемонстрировано в следующем примере:

Пример 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);        
  });

Оберните простое значение в обещание, используя $ q.when ()

Если все, что вам нужно, это превратить ценность в обещание, вам не нужно использовать длинный синтаксис, как здесь:

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

В этом случае вы можете просто написать:

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

$ q.when и его псевдоним $ q.resolve

Обертывает объект, который может быть значением или (сторонним), а затем - обещанием в обещание в $ q. Это полезно, когда вы имеете дело с объектом, который может или не может быть обещанием, или если обещание исходит от источника, которому нельзя доверять.

- AngularJS $ q Service API Reference - $ q.when


С выпуском AngularJS v1.4.1

Вы можете также использовать ES6-последовательный псевдоним resolve

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

Избегайте $ q отложенного анти-шаблона

Избегайте этого Anti-Pattern

var myDeferred = $q.defer();

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

return myDeferred.promise;

Нет необходимости $q.defer обещание с помощью $q.defer поскольку служба $ http уже возвращает обещание.

//INSTEAD
return $http(config);

Просто верните обещание, созданное службой $ http.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow