Odpowiedzi:
Tradycyjnym sposobem radzenia sobie z wywołaniami asynchronicznymi w JavaScript są wywołania zwrotne. Powiedzmy, że musieliśmy wykonać trzy połączenia z serwerem, jeden po drugim, aby skonfigurować naszą aplikację. W przypadku wywołań zwrotnych kod może wyglądać mniej więcej tak (przy założeniu funkcji xhrGET do wywołania serwera):
// 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
});
});
});
W tym przykładzie najpierw pobieramy konfigurację serwera. Następnie na tej podstawie pobieramy informacje o bieżącym użytkowniku, a następnie w końcu otrzymujemy listę elementów dla bieżącego użytkownika. Każde wywołanie xhrGET przyjmuje funkcję zwrotną, która jest wykonywana, gdy serwer odpowiada.
Oczywiście, im więcej poziomów zagnieżdżania mamy, tym trudniej jest czytać, debugować, utrzymywać, aktualizować i zasadniczo pracować z kodem. Jest to ogólnie znane jako piekło zwrotne. Ponadto, jeśli potrzebowaliśmy obsługiwać błędy, musimy przekazać inną funkcję do każdego wywołania xhrGET, aby powiedzieć mu, co należy zrobić w przypadku błędu. Jeśli chcielibyśmy mieć tylko jedną wspólną procedurę obsługi błędów, nie jest to możliwe.
Interfejs API Promise został zaprojektowany w celu rozwiązania tego problemu zagnieżdżania oraz problemu obsługi błędów.
Promise API proponuje następujące opcje:
promiseobiekt.promiseobiekt będzie miał thenfunkcję, która może przyjąć dwa argumenty, success
moduł obsługi i errormoduł obsługi.thenfunkcji zostanie wywołana tylko raz , po zakończeniu zadania asynchronicznego.thenFunkcja będzie również zwróci promise, w celu umożliwienia łączenia wielu połączeń.value, który zostanie przekazany do następnej funkcji jako argument, w łańcuchu promises.promise(wykonuje kolejne żądanie asynchroniczne), następny moduł obsługi (sukces lub błąd) zostanie wywołany dopiero po zakończeniu tego żądania.Tak więc poprzedni przykładowy kod może zostać przetłumaczony na coś takiego, jak przy użyciu obietnic i $httpusługi (w 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
}
);
Propagowanie sukcesu i błędu
Łańcuchowe obietnice to bardzo potężna technika, która pozwala nam osiągnąć wiele funkcji, takich jak wykonanie połączenia z serwerem, wykonanie częściowego przetwarzania danych, a następnie zwrócenie przetworzonych danych do kontrolera. Ale kiedy pracujemy z
promisełańcuchami, musimy pamiętać o kilku rzeczach.
Rozważ następujący hipotetyczny promisełańcuch z trzema obietnicami, P1, P2 i P3. Każdy promisema moduł obsługi sukcesu i moduł obsługi błędów, więc S1 i E1 dla P1, S2 i E2 dla P2 oraz S3 i E3 dla P3:
xhrCall()
.then(S1, E1) //P1
.then(S2, E2) //P2
.then(S3, E3) //P3
W normalnym przepływie rzeczy, gdzie nie ma błędów, aplikacja przepływałaby przez S1, S2, a na końcu S3. Ale w prawdziwym życiu rzeczy nigdy nie są tak płynne. P1 może napotkać błąd lub P2 może napotkać błąd, wyzwalając E1 lub E2.
Rozważ następujące przypadki:
• Otrzymujemy pozytywną odpowiedź z serwera w P1, ale zwrócone dane są niepoprawne lub brak danych na serwerze (pomyśl pusta tablica). W takim przypadku, dla następnej obietnicy P2, powinna ona uruchomić moduł obsługi błędów E2.
• Otrzymujemy błąd dla obietnicy P2, wyzwalający E2. Ale w module obsługi mamy dane z pamięci podręcznej, co zapewnia, że aplikacja może załadować się normalnie. W takim przypadku możemy chcieć upewnić się, że po E2 wywoływana jest S3.
Tak więc za każdym razem, gdy piszemy komunikat o sukcesie lub procedurze obsługi błędów, musimy wykonać połączenie - biorąc pod uwagę naszą obecną funkcję, czy ta obietnica jest sukcesem czy porażką następnego programu obsługi w łańcuchu obietnic?
Jeśli chcemy uruchomić procedurę obsługi sukcesu dla następnej obietnicy w łańcuchu, możemy po prostu zwrócić wartość z procedury sukcesu lub procedury obsługi błędów
Jeśli natomiast chcemy uruchomić moduł obsługi błędów dla następnej obietnicy w łańcuchu, możemy to zrobić za pomocą deferredobiektu i wywołania jego reject()metody
Co to jest odroczony obiekt?
Odroczone obiekty w jQuery reprezentują jednostkę pracy, która zostanie ukończona później, zazwyczaj asynchronicznie. Po zakończeniu jednostki pracy
deferredobiekt można ustawić jako rozwiązany lub nie powiódł się.
deferredObiektu zawierapromiseobiekt. Za pomocąpromiseobiektu możesz określić, co ma się stać po zakończeniu jednostki pracy. Robisz to, ustawiając funkcje wywołania zwrotnego napromiseobiekcie.
Odroczone obiekty w Jquery: https://api.jquery.com/jquery.deferred/
Odroczone obiekty w AngularJs: https://docs.angularjs.org/api/ng/service/ $ q
funkcja then () jest związana z „obietnicami Javascript” używanymi w niektórych bibliotekach lub frameworkach, takich jak jQuery lub AngularJS.
Obietnica jest wzorcem do obsługi operacji asynchronicznych. Obietnica umożliwia wywołanie metody o nazwie „następnie”, która umożliwia określenie funkcji, które mają być używane jako wywołania zwrotne.
Aby uzyskać więcej informacji, zobacz: http://wildermuth.com/2013/8/3/JavaScript_Promises
A dla obietnic Angular: http://liamkaufman.com/blog/2013/09/09/using-angularjs-promises/
A promise can only succeed or fail onceiIf a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called
Według mojej wiedzy, nie ma wbudowanej then()metody w javascript(w momencie pisania tego tekstu).
Wygląda na to, że cokolwiek doSome("task")zwraca, ma metodę o nazwie then.
Jeśli zarejestrujesz wynik powrotu doSome()do konsoli, powinieneś być w stanie zobaczyć właściwości tego, co zostało zwrócone.
console.log( myObj.doSome("task") ); // Expand the returned object in the
// console to see its properties.
AKTUALIZACJA (od ECMAScript6) : -
.then()Funkcja została włączona do czystego javascript.
Z dokumentacji Mozilli tutaj ,
Metoda then () zwraca obietnicę. Przyjmuje dwa argumenty: funkcje zwrotne dla przypadków sukcesu i niepowodzenia Obietnicy.
Z kolei obiekt Promise jest zdefiniowany jako
Obiekt Promise służy do obliczeń odroczonych i asynchronicznych. Obietnica oznacza operację, która nie została jeszcze zakończona, ale jest oczekiwana w przyszłości.
Oznacza to, że Promisedziała jako symbol zastępczy dla wartości, która nie została jeszcze obliczona, ale zostanie rozwiązana w przyszłości. I .then()funkcja służy do kojarzenia funkcji, które mają zostać wywołane w Obietnicy po jej rozwiązaniu - jako sukces lub porażka.
.thenWtedy nie było wbudowanego , ale natywne obietnice nadchodzą teraz w ES6: html5rocks.com/en/tutorials/es6/promises
Oto rzecz, którą sobie stworzyłem, aby wyjaśnić, jak działają rzeczy. Sądzę, że inni też mogą uznać ten konkretny przykład za użyteczny:
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>
to jest stos wywołania zwrotnego metody, który jest dostępny po rozwiązaniu obietnicy, jest częścią biblioteki takiej jak jQuery, ale teraz jest dostępny w natywnym JavaScript, a poniżej znajduje się szczegółowe wyjaśnienie, jak to działa
Możesz zrobić obietnicę w natywnym JavaScript: tak jak w jQuery są obietnice, każda obietnica może być układana w stos, a następnie może być wywoływana z wywołaniami zwrotnymi Resolve i Reject, w ten sposób możesz łączyć asynchroniczne wywołania.
Rozwidlałem i edytowałem z MSDN Docs na temat stanu ładowania baterii.
Spróbuje dowiedzieć się, czy użytkownik laptopa lub urządzenia ładuje baterię. jest wywoływany i możesz odnieść sukces w pracy.
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}`)
})
Definicja :: then jest metodą stosowaną do rozwiązywania asynchronicznych wywołań zwrotnych
zostało to wprowadzone w ES6
Odpowiednią dokumentację znajdziesz tutaj Obietnice Es6
thenpochodzi i jak działa. Powinieneś poprawić swoją odpowiedź, aby podać te szczegóły.
Podejrzewam, że doSome zwraca to, co jest myObj, która również ma metodę then. Standardowe łączenie metod ...
jeśli doSome nie zwraca tego, będąc obiektem, na którym wykonano doSome, bądź pewien, że zwraca jakiś obiekt za pomocą metody then ...
jak wskazuje @patrick, nie ma metody then () dla standardowego js
doSome („zadanie”) musi zwracać obiekt obietnicy, a obietnica ta zawsze ma funkcję wtedy. Twój kod jest taki jak ten
promise.then(function(env) {
// logic
});
i wiesz, że jest to zwykłe wywołanie funkcji członka.
.then zwraca obietnicę w funkcji asynchronicznej.
Dobrym przykładem byłoby:
var doSome = new Promise(function(resolve, reject){
resolve('I am doing something');
});
doSome.then(function(value){
console.log(value);
});
Aby dodać do niego kolejną logikę, możesz także dodać reject('I am the rejected param')wywołanie funkcji i console.log.
W tym przypadku then()jest metoda klasowa obiektu zwrócona przez doSome()metodę.
Funkcja „.then ()” jest szeroko stosowana dla obiecanych obiektów w programowaniu Asynchoronus dla aplikacji Windows 8 Store. O ile rozumiem, działa to jak połączenie zwrotne.
Znajdź szczegóły w tej dokumentacji http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx
Przyczyną może być również nazwa każdej innej zdefiniowanej funkcji.
Inny przykład:
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, ..) */
})
Ta sama logika przy użyciu skrótów funkcji strzałek:
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, ..) */
)
Spóźniłem się około 8 lat, cóż ... tak czy inaczej, tak naprawdę nie wiem, co wtedy () robi, ale może MDN może mieć odpowiedź. Właściwie mógłbym to trochę zrozumieć.
Spowoduje to wyświetlenie wszystkich potrzebnych informacji (mam nadzieję). Chyba że ktoś już opublikował ten link. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
Format to promise.prototype.then () Obietnica i prototyp są jakby podobnymi zmiennymi, ale nie podobnymi zmiennymi w javascript, mam na myśli, że inne rzeczy idą tam jak navigator.getBattery (). Then (), gdzie to istnieje, ale jest ledwo używany w sieci, ten pokazuje status baterii urządzenia, więcej informacji i więcej na MDN, jeśli jesteś ciekawy.