Сервіс $q та promise-об’єкти
Promise є результатом виконання асинхронної операції. Promise-об'єкт визначає методи, які реєструють функцію, що викликається після завершення асинхронної операції. Переробимо попередній приклад так, щоб він використовував promise-об'єкт та сервіс $q. Файл із даними у форматі json залишається тим самим. Винесемо всі дії щодо завантаження даних в окремий сервіс. Нехай це буде файл dataService.js з таким вмістом:
По суті цей сервіс нагадує той же, що робився в першій темі цієї глави. У метод questApp.factory передаємо назву сервісу та функцію, яка приймає два параметри - $http та $q. Далі у функції getData ми створюємо об'єкт deferred: var deferred = $q.defer();
Суть створення deferred-об'єкта полягає в тому, що він розкриває, по-перше, api з виконання операцій. А по-друге, він містить асоційований promise-об'єкт, і через deferred-об'єкт ми взаємодіємо з promise-об'єктом. Щоб отримати promise-об'єкт, наприкінці функції використовується наступний вираз return deferred.promise .
Якщо запит увінчався успіхом, то викликаємо метод deferred.resolve(data.question); . Цей метод зіставляє дані з promise-об'єктом. В результаті виклик return deferred.promise поверне нам завантажені дані.
Якщо запит пройшов невдало, викликається метод deferred.reject(status)
Контролер у нас видозміниться так:
Оскільки у вищевизначеному сервісі функція getData повертає promise-об'єкт, який у свою чергу містить усі завантажені дані, ми можемо просто привласнити ці дані: var promiseObj=dataService.getData();
У той же час важливо розуміти, що тепер promiseObj представлятиме не простий javascript-об'єкт, а саме promise-об'єкт, що накладає деякі обмеженняйого використання.
Щоб отримати чистий JavaScript-об'єкт, можна використовувати функцію promiseObj.then , яка має наступний синтаксис: then(successCallback, errorCallback, notifyCallback)
Параметр successCallback представляє функцію, яка виконується при успішному завершенні дії. Функція, що передається як параметр errorCallback, навпаки, виконується при невдалому завершенні дії. І функція, представлена параметром notifyCallback, може виконуватися як індикатор виконання дії.
У нашому випадку ми використовували тільки перший параметр - функцію вдалого виконання дії, а як параметр у неї передається безпосередньо завантажений з сервера об'єкт.