Próbuję korzystać z nowych funkcji asynchronicznych i mam nadzieję, że rozwiązanie mojego problemu pomoże innym w przyszłości. To jest mój kod, który działa:
async function asyncGenerator() {
// other code
while (goOn) {
// other code
var fileList = await listFiles(nextPageToken);
var parents = await requestParents(fileList);
// other code
}
// other code
}
function listFiles(token) {
return gapi.client.drive.files.list({
'maxResults': sizeResults,
'pageToken': token,
'q': query
});
}
Problem polega na tym, że moja pętla while działa zbyt szybko, a skrypt wysyła zbyt wiele żądań na sekundę do interfejsu API Google. Dlatego chciałbym zbudować funkcję uśpienia, która opóźnia żądanie. W ten sposób mógłbym również użyć tej funkcji do opóźnienia innych żądań. Jeśli istnieje inny sposób opóźnienia żądania, daj mi znać.
W każdym razie to mój nowy kod, który nie działa. Odpowiedź żądania jest zwracana do anonimowej funkcji asynchronicznej w ramach setTimeout, ale po prostu nie wiem, jak mogę zwrócić odpowiedź na funkcję uśpienia lub. do początkowej funkcji asyncGenerator.
async function asyncGenerator() {
// other code
while (goOn) {
// other code
var fileList = await sleep(listFiles, nextPageToken);
var parents = await requestParents(fileList);
// other code
}
// other code
}
function listFiles(token) {
return gapi.client.drive.files.list({
'maxResults': sizeResults,
'pageToken': token,
'q': query
});
}
async function sleep(fn, par) {
return await setTimeout(async function() {
await fn(par);
}, 3000, fn, par);
}
Próbowałem już kilka opcji: przechowywanie odpowiedzi w zmiennej globalnej i zwrócenie jej z funkcji uśpienia, wywołanie zwrotne w funkcji anonimowej itp.
źródło
Promise.all
podejście. Tak prosty i elegancki!var [parents]
? Nie widziałem tego wcześniej i trudno google googleasync function
.async
/await
jest na podstawie obietnic. Jedyne, co zastępuje, tothen
połączenia.Od Węzła 7.6 możesz łączyć funkcje
promisify
funkcji z modułu utils zsetTimeout()
.Node.js
JavaScript
Stosowanie
źródło
await require('util').promisify(setTimeout)(3000)
można również osiągnąć bez konieczności:await setTimeout[Object.getOwnPropertySymbols(setTimeout)[0]](3000)
getOwnPropertySymbols
wersja ... jeśli nie jest zepsuta ...!Szybki, liniowy, liniowy sposób
źródło
let sleep = ms => new Promise( r => setTimeout(r, ms));
// funkcja jednegoawait new Promise(resolve => setTimeout(resolve, 5000))
setTimeout
nie jestasync
funkcją, więc nie można jej używać z asynchronicznym oczekiwaniem na ES7. Ale możesz zaimplementować swojąsleep
funkcję za pomocą ES6 Promise :Następnie będziesz mógł użyć tej nowej
sleep
funkcji z asynchronicznym oczekiwaniem na ES7:Pamiętaj , że odpowiadam tylko na twoje pytanie dotyczące połączenia asynchronicznego / oczekującego ES7 z
setTimeout
, choć może nie pomóc rozwiązać problemu z wysyłaniem zbyt wielu żądań na sekundę.Aktualizacja: Nowoczesne wersje node.js mają wbudowaną implementację limitu czasu asynchronicznego dostępu, dostępną za pośrednictwem pomocnika util.promisify :
źródło
fn
rzuty nie zostaną złapane.new Promise
tam, gdzie możeszsleep.catch
.setTimeout
wywołaniu zwrotnym, anew Promise
wywołanie zwrotne zostało wykonane przez długi czas. Zostanie przeniesiony do kontekstu globalnego i zostanie zgłoszony jako nieobsługiwany wyjątek.Jeśli chcesz użyć tego samego rodzaju składni, jak
setTimeout
możesz napisać funkcję pomocniczą w następujący sposób:Możesz to tak nazwać:
Zrobiłem sedno: https://gist.github.com/DaveBitter/f44889a2a52ad16b6a5129c39444bb57
źródło
delayRun
bardziej sensowna byłaby tutaj nazwa funkcji , ponieważ opóźni ona uruchomienie funkcji zwrotnej o X sekund. Niezbyt oczekiwany przykład, IMO.źródło
Poniższy kod działa w Chrome i Firefox i być może w innych przeglądarkach.
Ale w Internet Explorerze pojawia się błąd składni dla
"(resolve **=>** setTimeout..."
źródło
Popełnił util inspirowane z Dave „s odpowiedź
Zasadniczo przekazano w
done
wywołaniu zwrotnym, aby zadzwonić po zakończeniu operacji.Tak to wykorzystuję:
źródło
To jest moja wersja z nodejs teraz w 2020 roku w labdas AWS
źródło
Jest to szybsze rozwiązanie w jednej linijce.
Mam nadzieję, że to pomoże.
źródło
await setTimeout(()=>{console.log('first')}, 200); console.log ('second')
drukuje drugi, a potem pierwszyvar test = async () => { await setTimeout(()=>{console.log('first')}, 1000); console.log ('second') }
Wydłużyłem limit czasu, aby pokazać jego przydatność.