Ответы:
Традиционный способ обработки асинхронных вызовов в 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, который будет передан следующей функции как a 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
Функция then () связана с «обещаниями JavaScript», которые используются в некоторых библиотеках или инфраструктурах, таких как jQuery или AngularJS.
Обещание - это шаблон для обработки асинхронных операций. Обещание позволяет вам вызывать метод с именем «then», который позволяет вам указать функции, которые будут использоваться в качестве обратных вызовов.
Для получения дополнительной информации см .: 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 здесь ,
Метод then () возвращает Promise. Он принимает два аргумента: функции обратного вызова для случаев успеха и неудачи Обещания.
Объект Promise, в свою очередь, определяется как
Объект 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, Каждое обещание может быть сложено, а затем может быть вызвано с помощью обратных вызовов Resolve и Reject. Так вы можете связывать асинхронные вызовы.
Я разветвлялся и редактировал документы 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}`)
})
Definition :: then - метод, используемый для решения асинхронных обратных вызовов.
это введено в ES6
Пожалуйста, найдите соответствующую документацию здесь Es6 Promises
thenи как он работает. Вы должны улучшить свой ответ, чтобы предоставить эти детали.
Я подозреваю, что doSome возвращает this, это myObj, который также имеет метод then. Стандартный метод цепочки ...
если doSome не возвращает это, будучи объектом, на котором был выполнен doSome, будьте уверены, что он возвращает некоторый объект с помощью метода then ...
как указывает @patrick, для стандартных js нет then ()
.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.
doSome ("задача") должна возвращать объект обещания, и это обещание всегда имеет функцию then. Так что ваш код такой же, как этот
promise.then(function(env) {
// logic
});
и вы знаете, что это просто обычный вызов функции-члена.
В данном случае then()это метод класса объекта, возвращаемого doSome()методом.
Функция ".then ()" широко используется для обещанных объектов в программировании Asynchoronus для приложений Магазина Windows 8. Насколько я понял, это работает как обратный вызов.
Найти подробности в этом документе 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
Формат - promise.prototype.then (). Обещание и прототип в некотором роде похожи на переменные, но не похожи на переменные в javascript. Я имею в виду, как и другие вещи, такие как navigator.getBattery (). Then (), где это на самом деле существует, но он едва используется в Интернете, показывает статусы батареи устройства, дополнительную информацию и дополнительную информацию о MDN, если вам интересно.