Как результат передается от объекта $ http до неназванной функции, которая выполняется при успешном завершении?
$http
.success(function (result) {
...
})
Я знаю, что результат передается через любое имя переменной, которое я ввел в функцию. Его обычно называют result
. Но как это делается? Для меня это похоже на волшебство.
Я ожидал бы написать что-то вроде:
$http
.success(function (result=$http.result) {
...
})
Вы должны изучить, как работают Javascript Function Parameters and Promises.
Код, который вы вставили, приходит, я думаю, из некоторого приложения AngularJS.
Если мое предположение верно, $ http является сервисом и не имеет ни одного метода успеха.
Метод успеха присутствует в методах $ http:
//get, post, ecc...
$http.get(...).success()
Кстати:
function loggerCase1(log1, log2, log3, log4) {
console.log('loggerCase1 => param-1:', log1);
console.log('loggerCase1 => param-2:', log2);
console.log('loggerCase1 => param-3:', log3);
console.log('loggerCase1 => param-4:', log4);
console.log('---------------------');
};
function loggerCase2(log4, log2, log1, log3) {
console.log('loggerCase2 => param-1:', log4);
console.log('loggerCase2 => param-2:', log2);
console.log('loggerCase2 => param-3:', log1);
console.log('loggerCase2 => param-4:', log3);
console.log('---------------------');
};
function loggerCaseN() {
for(var i = 0; i < arguments.length; i++) {
console.log('loggerCaseN => param-' + (i + 1) + ': ', arguments[i]);
}
console.log('---------------------');
};
var logs = ['log1', 'log2', 'log3', 'log4'];
loggerCase1.apply(this, logs);
loggerCase2.apply(this, logs);
loggerCaseN.apply(this, logs);
Если все понятно о поведении функциональных параметров в javascript... вы узнаете, что не можете сказать, что дайте мне первый как второй или что-то в этом роде, также пример, который вы вставили, похоже на параметры по умолчанию (реализованные в ES6, а также Javascript Harmony).
Переходим к точке 2:
angular
.module('promisechainging', [])
.run(function($q) {
$q
.when('Hello World')
.then(function(greetings) {
console.log('ring 1', greetings);
return greetings;
})
.then(function(salut) {
console.log('ring 2', salut);
return salut;
})
.then(function(ciao) {
console.log('ring 3', ciao);
return { message: ciao };
})
.then(function(result) {
console.log('ring 4', result.message);
return result;
})
.catch(function(error) {
console.log('THIS LOG NEVER HAPPENS BECAUSE THERE AREN\'T REJECTED PROMISES');
return $q.reject(error);
})
.finally(function() {
console.log('We Are At The END');
})
;
})
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="promisechainging"></div>
$http
.success(function (result) {
...
})
$http
будет возвращать объект Promise Object
который является не чем иным, как Javascript Object с success
и другими другими функциями.
Таким образом, утверждение немедленно становится как ниже, поскольку оценивается $http
,
(Promise Object)
.success(function (result) {
...
})
Функция success
обещания сохранит эту анонимную функцию, которая будет называться после того, как обещание будет разрешено. Мы можем вручную решить обещания, но, я думаю, http сделает это для вас здесь.
Как только HTTP-запрос (AJAX) будет успешным угловым, он сообщит об этом объекте Promise, чтобы запустить эту функцию успеха, разрешив обещание, что-то вроде:
suceess: function(responseData){ //success of AJAX
resolve(responseData); //this will pass the result to promise
}
После того как resolve
называется объектом обетования, имеет результат с ним, он затем вызовет функцию успеха, которую вы перенесли изначально с этим значением результата.
PS: Это грубая идея, я хочу посмотреть в Угловой источник, чтобы увидеть их реальную реализацию.
$http
позволяет выполнять асинхронные сетевые операции и возвращает объект обещания (вы можете больше узнать о обещаниях в Angular здесь).
Методы success
и error
использовались для объявления обратных вызовов того, что происходит, когда обещание разрешено (когда запрос был успешно завершен) или отклонен (при возникновении ошибки при обработке запроса). Я использовал в прошедшее время, так как они теперь осуждаются и желаемый способ справиться с этим использует then
метод объекта посыла.
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
В принципе, синтаксис почти то же самое - successCallbackFunction имеет ту же подпись, что и метод, который вы проходили в методе success
вашего примера.
Но это только подпись метода. Параметры функции обратного вызова можно вызвать, но вы хотите (result
, data
т.д.). Все, о чем вы должны помнить, это то, что первым параметром в вашей функции обратного вызова будут данные, возвращаемые вашим запросом.
Угловой использует механизм обещаний, который в основном возвращает объект, который позволяет вам знать, когда результат доступен, или была сброшена ошибка.
Когда вызов ajax возвращается, угловой вызов обещания и предоставление результата в качестве параметра.
Это как вызов обычной функции.
Функции Javascript также являются объектами класса.
Когда $ http завершает работу, он вызовет либо функцию успеха, либо неудачу - они являются объектами, поэтому их можно обойти. Когда это произойдет, оно предоставит параметры.