Відповіді:
Традиційним способом роботи з асинхронними дзвінками в JavaScript був зворотний зв'язок. Скажіть, що нам потрібно було здійснити три дзвінки на сервер, один за одним, щоб налаштувати нашу програму. З зворотними дзвінками код може виглядати приблизно так (припускаючи функцію xhrGET для здійснення серверного виклику):
// Fetch some server configuration
xhrGET('/api/server-config', function(config) {
// Fetch the user information, if he's logged in
xhrGET('/api/' + config.USER_END_POINT, function(user) {
// Fetch the items for the user
xhrGET('/api/' + user.id + '/items', function(items) {
// Actually display the items here
});
});
});
У цьому прикладі ми спочатку забираємо конфігурацію сервера. Потім виходячи з цього, ми отримуємо інформацію про поточного користувача, а потім нарешті отримуємо список елементів для поточного користувача. Кожен дзвінок xhrGET приймає функцію зворотного виклику, яка виконується, коли сервер відповідає.
Тепер, звичайно, чим більше рівнів вкладення у нас, тим важче читати код, налагоджувати, підтримувати, оновлювати та в основному працювати. Це загалом відомо як пекло зворотного дзвінка. Крім того, якщо нам потрібно було обробляти помилки, нам, можливо, потрібно передати іншу функцію кожному виклику xhrGET, щоб повідомити, що йому потрібно робити у випадку помилки. Якщо ми хотіли мати лише один загальний обробник помилок, це неможливо.
API Promise був розроблений для вирішення цієї проблеми введення та проблеми з помилками.
API Promise пропонує наступне:
promiseоб'єкт.promiseоб’єкт матиме thenфункцію, яка може приймати два аргументи, success
обробник та errorобробник.thenфункції буде викликаний лише один раз , після закінчення асинхронної задачі.thenФункція також буде повертати promise, щоб зчеплення декількох викликів.value, який буде переданий наступній функції як argument, у ланцюжку promises.promise(робить інший асинхронний запит), наступний обробник (успіх чи помилка) буде викликаний лише після завершення цього запиту.Отже попередній приклад коду може перекласти щось на зразок наступного, використовуючи обіцянки та $httpпослугу (в AngularJs):
$http.get('/api/server-config').then(
function(configResponse) {
return $http.get('/api/' + configResponse.data.USER_END_POINT);
}
).then(
function(userResponse) {
return $http.get('/api/' + userResponse.data.id + '/items');
}
).then(
function(itemResponse) {
// Display items here
},
function(error) {
// Common error handling
}
);
Поширення успіху та помилки
Зв'язування обіцянок - це дуже потужна методика, яка дозволяє нам виконати багато функціональних можливостей, як, наприклад, сервіс здійснює дзвінок на сервер, виконує деяку пост-обробку даних, а потім повертає оброблені дані в контролер. Але коли ми працюємо з
promiseланцюжками, ми маємо пам’ятати кілька речей.
Розглянемо наступний гіпотетичний promiseланцюг з трьома обіцянками, P1, P2, і P3. Кожен promiseмає обробник успіху та обробку помилок, тому S1 і E1 для P1, S2 і E2 для P2, а S3 і E3 для P3:
xhrCall()
.then(S1, E1) //P1
.then(S2, E2) //P2
.then(S3, E3) //P3
У нормальному потоці речей, де немає помилок, додаток протікає через S1, S2 і, нарешті, S3. Але в реальному житті все ніколи не буває таким гладким. P1 може зіткнутися з помилкою, або P2 може зіткнутися з помилкою, викликаючи E1 або E2.
Розглянемо наступні випадки:
• Ми отримуємо успішну відповідь від сервера в P1, але повернені дані невірні або на сервері немає даних (думаю, порожній масив). У такому випадку для наступної обіцянки P2 він повинен викликати оброблювач помилок E2.
• Ми отримуємо помилку за обіцянку P2, запускаючи E2. Але всередині обробника ми маємо дані з кешу, гарантуючи, що програма може завантажуватися як звичайна. У цьому випадку ми можемо захотіти, щоб після E2 викликався S3.
Отже, кожного разу, коли ми пишемо успіх чи обробку помилок, нам потрібно телефонувати - враховуючи нашу поточну функцію, чи обіцяє це успіх чи провал для наступного обробника в ланцюжку обіцянок?
Якщо ми хочемо викликати обробник успіху для наступної обіцянки ланцюга, ми можемо просто повернути значення успіху чи обробника помилок
Якщо, з іншого боку, ми хочемо запустити оброблювач помилок для наступної обіцянки в ланцюзі, ми можемо це зробити за допомогою deferredоб'єкта та виклику його reject()методу
Тепер Що таке відкладений об’єкт?
Відкладені об'єкти в jQuery являють собою одиницю роботи, яка буде завершена пізніше, як правило, асинхронно. Після того, як одиниця роботи завершена,
deferredоб'єкт може бути встановлений на розв’язаний або збій.
deferredОб'єкт міститьpromiseоб'єкт. Черезpromiseоб'єкт ви можете вказати, що має відбуватися, коли блок роботи закінчується. Ви робите це, встановлюючи наpromiseоб'єкті функції зворотного дзвінка .
Відкладені об'єкти в Jquery: https://api.jquery.com/jquery.deferred/
Відкладені об'єкти в AngularJs: https://docs.angularjs.org/api/ng/service/ $ q
тоді () функція пов'язана з "обіцянками Javascript", які використовуються в деяких бібліотеках або структурах, таких як jQuery або AngularJS.
Обіцянка - зразок для асинхронних операцій. Обіцянка дозволяє викликати метод, який називається "тоді", який дозволяє вказати функції (и), які будуть використовуватись як зворотні дзвінки.
Для отримання додаткової інформації див: http://wildermuth.com/2013/8/3/JavaScript_Promises
А щодо кутових обіцянок: http://liamkaufman.com/blog/2013/09/09/using-angularjs-promises/
A promise can only succeed or fail onceіIf a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called
Наскільки мені відомо, не існує вбудованого then()методу javascript(на момент написання цього тексту).
Здається, що все, що doSome("task")повертається, має метод, який називається then.
Якщо ви записуєте результат повернення doSome()на консоль, ви повинні мати можливість бачити властивості повернутого.
console.log( myObj.doSome("task") ); // Expand the returned object in the
// console to see its properties.
ОНОВЛЕННЯ (Станом на ECMAScript6) : -
.then()Функція була включена в чистому JavaScript.
З документації Mozilla тут ,
Метод тоді () повертає Обіцянку. Це потребує двох аргументів: функції зворотного виклику для випадків успіху та відмови Обіцянки.
Об'єкт Обіцяння, у свою чергу, визначається як
Об'єкт Promise використовується для відкладених та асинхронних обчислень. Обіцянка - це операція, яка ще не завершена, але очікується в майбутньому.
Тобто, Promiseвиступає як заповнювач цінності, яка ще не обчислена, але повинна бути вирішена в майбутньому. І ця .then()функція використовується для асоціації функцій, які потрібно викликати в Обіцянні, коли вона буде вирішена - або як успіх чи невдача.
.then, але в ES6 зараз надходять вітчизняні обіцянки: html5rocks.com/en/tutorials/es6/promises
Ось, що я зробив для себе, щоб зрозуміти, як все працює. Я думаю, що й цей конкретний приклад може бути корисним:
doit().then(function() { log('Now finally done!') });
log('---- But notice where this ends up!');
// For pedagogical reasons I originally wrote the following doit()-function so that
// it was clear that it is a promise. That way wasn't really a normal way to do
// it though, and therefore Slikts edited my answer. I therefore now want to remind
// you here that the return value of the following function is a promise, because
// it is an async function (every async function returns a promise).
async function doit() {
log('Calling someTimeConsumingThing');
await someTimeConsumingThing();
log('Ready with someTimeConsumingThing');
}
function someTimeConsumingThing() {
return new Promise(function(resolve,reject) {
setTimeout(resolve, 2000);
})
}
function log(txt) {
document.getElementById('msg').innerHTML += txt + '<br>'
}
<div id='msg'></div>
тоді це стек зворотного виклику методу, який доступний після вирішення обіцянки, це частина бібліотеки, як jQuery, але тепер вона доступна в рідному JavaScript і нижче - детальне пояснення, як це працює
Ви можете зробити Обіцяння на рідному JavaScript: так само, як є обіцянки в jQuery, кожну обіцянку можна скласти, а потім можна викликати за допомогою вирішення та відхилення зворотних викликів. Ось як можна ланцюг асинхронних дзвінків.
Я роздвоював і редагував у Документах MSDN про стан зарядки акумулятора.
Для цього потрібно спробувати з'ясувати, чи ноутбук або пристрій заряджає акумулятор. потім називається, і ви можете зробити успіх своєї роботи.
navigator
.getBattery()
.then(function(battery) {
var charging = battery.charging;
alert(charging);
})
.then(function(){alert("YeoMan : SINGH is King !!");});
function fetchAsync (url, timeout, onData, onError) {
…
}
let fetchPromised = (url, timeout) => {
return new Promise((resolve, reject) => {
fetchAsync(url, timeout, resolve, reject)
})
}
Promise.all([
fetchPromised("http://backend/foo.txt", 500),
fetchPromised("http://backend/bar.txt", 500),
fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
let [ foo, bar, baz ] = data
console.log(`success: foo=${foo} bar=${bar} baz=${baz}`)
}, (err) => {
console.log(`error: ${err}`)
})
Визначення :: тоді - це метод, що використовується для вирішення асинхронних зворотних викликів
це введено в ES6
Ви можете знайти необхідні документи тут ES6 Promises
thenі як він працює. Вам слід покращити свою відповідь, щоб надати ці деталі.
Я підозрюю, що doSome повертає це, що є myObj, який також має тодішній метод. Стандартний метод ланцюга ...
якщо doSome не повертає це, будучи об'єктом, над яким виконано doSome, будьте впевнені, що він повертає якийсь об'єкт методом тоді ...
як вказує @patrick, для стандартних js немає тоді ()
doSome ("завдання") повинен повертати об'єкт обіцянки, і ця обіцянка завжди має функцію "тоді". Отже, ваш код саме такий
promise.then(function(env) {
// logic
});
і ви знаєте, що це лише звичайний виклик функції члена.
.then повертає обіцянку в функції асинхронізації.
Хорошим прикладом може бути:
var doSome = new Promise(function(resolve, reject){
resolve('I am doing something');
});
doSome.then(function(value){
console.log(value);
});
Щоб додати до нього іншу логіку, ви також можете додати функцію reject('I am the rejected param')виклику та console.log.
У цьому випадку then()- клас класу об'єкта, що повертається doSome()методом.
Функція ".then ()" широко використовується для обіцяних об'єктів в програмі Asynchoronus для програм Windows 8 Store. Наскільки я зрозумів, це працює так, як зворотний виклик.
Деталі можна знайти в цьому документі http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx
З причини, це також може бути назва будь-якої іншої визначеної функції.
Ще один приклад:
new Promise(function(ok) {
ok(
/* myFunc1(param1, param2, ..) */
)
}).then(function(){
/* myFunc1 succeed */
/* Launch something else */
/* console.log(whateverparam1) */
/* myFunc2(whateverparam1, otherparam, ..) */
}).then(function(){
/* myFunc2 succeed */
/* Launch something else */
/* myFunc3(whatever38, ..) */
})
Ця ж логіка, що використовує стрілочні функції скорочення:
new Promise((ok) =>
ok(
/* myFunc1(param1, param2, ..) */
)).then(() =>
/* myFunc1 succeed */
/* Launch something else */
/* Only ONE call or statment can be made inside arrow functions */
/* For example, using console.log here will break everything */
/* myFunc2(whateverparam1, otherparam, ..) */
).then(() =>
/* myFunc2 succeed */
/* Launch something else */
/* Only ONE call or statment can be made inside arrow functions */
/* For example, using console.log here will break everything */
/* myFunc3(whatever38, ..) */
)
Я запізнююся на 8 років, ну ... все одно, я не знаю, що тоді () робить, але, можливо, MDN може відповісти. Насправді я насправді можу це зрозуміти трохи більше.
Це покаже вам всю інформацію (сподіваємось), що вам потрібна. Якщо хтось уже не опублікував це посилання. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
Формат - Promet.prototype.then () Обіцянка та прототип - це на зразок змінних, але не схожі на змінні в JavaScript, я маю на увазі, як інші речі йдуть туди, як navigator.getBattery (). ледь використовується в Інтернеті, цей показ показує статуси про акумулятор пристрою, більше інформації та багато іншого про MDN, якщо вам цікаво.