Sprawdź ten kod :
<a href="#" id="link">Link</a>
<span>Moving</span>
$('#link').click(function () {
console.log("Enter");
$('#link').animate({ width: 200 }, 2000, function() {
console.log("finished");
});
console.log("Exit");
});
Jak widać w konsoli, funkcja „animate” jest asynchroniczna i „rozwidla” przepływ kodu blokowego modułu obsługi zdarzeń. W rzeczywistości :
$('#link').click(function () {
console.log("Enter");
asyncFunct();
console.log("Exit");
});
function asyncFunct() {
console.log("finished");
}
podążaj za przepływem kodu blokowego!
Jeśli chcę utworzyć plik function asyncFunct() { }
z takim zachowaniem, jak mogę to zrobić za pomocą javascript / jquery? Myślę, że jest to strategia bez użycia setTimeout()
javascript
jquery
function
asynchronous
markzzz
źródło
źródło
Odpowiedzi:
Nie można utworzyć prawdziwie niestandardowej funkcji asynchronicznej. W końcu będziesz musiał wykorzystać technologię dostarczaną natywnie, taką jak:
setInterval
setTimeout
requestAnimationFrame
XMLHttpRequest
WebSocket
Worker
onload
W rzeczywistości do animacji jQuery używa
setInterval
.źródło
setInterval
), ale nie możemy jej nawet otworzyć, aby zobaczyć, jak to się robi. Masz więcej informacji na ten temat?setImmediate
promises
. Czy to dajeawaitable
?Możesz użyć timera:
(gdzie
yourFn
jest odniesienie do twojej funkcji)lub z Lodash :
źródło
setTimeout
to 4 milisekundy według specyfikacji HTML5. Nadanie mu 0 nadal zajmie minimalną ilość czasu. Ale tak, działa dobrze jako odrocznik funkcji.tutaj masz proste rozwiązanie (inni o tym piszą) http://www.benlesh.com/2012/05/calling-javascript-function.html
A oto gotowe rozwiązanie:
TEST 1 ( może wyświetlać '1 x 2 3' lub '1 2 x 3' lub '1 2 3 x' ):
TEST 2 ( zawsze wyświetla 'x 1' ):
Ta funkcja jest wykonywana z limitem czasu 0 - będzie symulować zadanie asynchroniczne
źródło
console.log(1)
jest wywoływana, a output (undefined
) jest przekazywany jako drugi argument doasync()
. W przypadku TESTU 1 myślę, że nie w pełni rozumiesz kolejkę wykonywania JavaScript. Ponieważ każde wywołanie, które maconsole.log()
miejsce na tym samym stosie,x
jest rejestrowane jako ostatnie. Głosowałbym w dół na tę odpowiedź za dezinformację, ale nie mam wystarczającej liczby powtórzeń.async(function() {console.log('x')}, function(){console.log(1)});
.TEST 2 as: async(function() {console.log('x')}, function(){console.log(1)});
- już to poprawiłemOto funkcja, która przyjmuje inną funkcję i wyprowadza wersję, która działa asynchronicznie.
Jest używany jako prosty sposób na utworzenie funkcji asynchronicznej:
Różni się to od odpowiedzi @ fider, ponieważ sama funkcja ma swoją własną strukturę (bez dodanego wywołania zwrotnego, jest już w funkcji), a także dlatego, że tworzy nową funkcję, której można użyć.
źródło
(function(a){ asyncFunction(a); })(a)
setTimeout(asyncFunction, 0, a);
Edycja: całkowicie źle zrozumiałem pytanie. W przeglądarce użyłbym
setTimeout
. Gdyby ważne było, aby działał w innym wątku, użyłbym Web Workers .źródło
Późno, ale aby pokazać proste rozwiązanie
promises
po ich wprowadzeniu w ES6 , o wiele łatwiej obsługuje wywołania asynchroniczne:Ustawiasz kod asynchroniczny w nowej obietnicy:
Uwaga, aby ustawić,
resolve()
kiedy zakończy się połączenie asynchroniczne.Następnie dodajesz kod, który chcesz uruchomić po zakończeniu wywołania asynchronicznego wewnątrz
.then()
obietnicy:Oto jego fragment:
lub JSFiddle
źródło
Ta strona przeprowadzi Cię przez podstawy tworzenia asynchronicznej funkcji javascript.
Od ES2017 asynchroniczne funkcje javacript są znacznie łatwiejsze do napisania. Powinieneś także przeczytać więcej na Obietnice .
źródło
Jeśli chcesz używać parametrów i regulować maksymalną liczbę funkcji asynchronicznych, możesz użyć prostego pracownika asynchronicznego, który zbudowałem:
Możesz go używać w ten sposób:
źródło
Chociaż nie różni się zasadniczo od innych rozwiązań, myślę, że moje rozwiązanie ma kilka dodatkowych fajnych rzeczy:
Function.prototype
umożliwienia ładniejszego nazwania tegoRównież podobieństwo do funkcji wbudowanej
Function.prototype.apply
wydaje mi się odpowiednie.źródło
Oprócz świetnej odpowiedzi @pimvdb i na wypadek, gdybyś się zastanawiał, async.js również nie oferuje prawdziwie asynchronicznych funkcji. Oto (bardzo) uproszczona wersja głównej metody biblioteki:
Tak więc funkcja chroni przed błędami i wdzięcznie przekazuje ją do wywołania zwrotnego do obsługi, ale kod jest tak samo synchroniczny jak każda inna funkcja JS.
źródło
Niestety JavaScript nie zapewnia funkcji asynchronicznej. Działa tylko w jednym wątku. Ale większość nowoczesnych przeglądarek zapewnia
Worker
s , czyli drugie skrypty, które są wykonywane w tle i mogą zwracać wynik. Tak więc doszedłem do rozwiązania, które uważam za przydatne do asynchronicznego uruchamiania funkcji, która tworzy proces roboczy dla każdego wywołania asynchronicznego.Poniższy kod zawiera funkcję
async
do wywołania w tle.Oto przykład użycia:
To wykonuje funkcję, która iteruje a
for
z ogromną liczbą, aby zająć trochę czasu jako demonstracja asynchroniczności, a następnie pobiera podwojenie podanej liczby.async
Metoda zapewniafunction
która wywołuje żądaną funkcję w tle, a to, co jest przewidziane jako parametrasync
wywołania zwrotne zereturn
w jego unikalny parametr. Więc w funkcji zwrotnejalert
otrzymuję wynik.źródło
MDN ma dobry przykład użycia setTimeout zachowującego „this”.
Jak poniżej:
źródło