Ich versuche, die neuen asynchronen Funktionen zu verwenden, und hoffe, dass die Lösung meines Problems in Zukunft anderen helfen wird. Dies ist mein Code, der funktioniert:
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
});
}
Das Problem ist, dass meine while-Schleife zu schnell ausgeführt wird und das Skript zu viele Anforderungen pro Sekunde an die Google-API sendet. Daher möchte ich eine Sleep-Funktion erstellen, die die Anfrage verzögert. Somit könnte ich diese Funktion auch verwenden, um andere Anfragen zu verzögern. Wenn es eine andere Möglichkeit gibt, die Anfrage zu verzögern, lassen Sie es mich bitte wissen.
Auf jeden Fall ist dies mein neuer Code, der nicht funktioniert. Die Antwort der Anfrage wird an die anonyme asynchrone Funktion innerhalb von setTimeout zurückgegeben, aber ich weiß einfach nicht, wie ich die Antwort an die Sleep-Funktion bzw. die Sleep-Funktion zurückgeben kann. zur anfänglichen asyncGenerator-Funktion.
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);
}
Ich habe bereits einige Optionen ausprobiert: Speichern der Antwort in einer globalen Variablen und Zurückgeben von der Sleep-Funktion, Rückruf innerhalb der anonymen Funktion usw.
quelle
Promise.all
Ansatz. So einfach und elegant!var [parents]
? Ich habe es noch nie gesehen und es ist eine schwierige Sache zu googelnasync function
.async
/await
wird auf Basis verspricht. Das einzige, was es ersetzt, sindthen
Anrufe.Seit Knoten 7.6 können Sie die
promisify
Funktionsfunktion aus dem Utils-Modul mit kombinierensetTimeout()
.Node.js
Javascript
Verwendung
quelle
await require('util').promisify(setTimeout)(3000)
kann auch ohne Bedarf erreicht werden durch:await setTimeout[Object.getOwnPropertySymbols(setTimeout)[0]](3000)
getOwnPropertySymbols
Version ... wenn sie nicht kaputt ist ...!Der schnelle Einzeiler inline
quelle
let sleep = ms => new Promise( r => setTimeout(r, ms));
// eineawait new Promise(resolve => setTimeout(resolve, 5000))
setTimeout
ist keineasync
Funktion, daher können Sie sie nicht mit ES7 async-await verwenden. Sie können Ihresleep
Funktion jedoch mit ES6 Promise implementieren :Dann können Sie diese neue
sleep
Funktion mit ES7 async-await verwenden:Bitte beachten Sie, dass ich nur Ihre Frage zum Kombinieren von ES7 async / await mit beantworte
setTimeout
, obwohl dies möglicherweise nicht zur Lösung Ihres Problems beim Senden zu vieler Anfragen pro Sekunde beiträgt .Update: Moderne node.js-Versionen verfügen über eine integrierte asynchrone Timeout-Implementierung, auf die über den Hilfsprogramm util.promisify zugegriffen werden kann :
quelle
fn
Würfe den Fehler nicht abfangen würden.new Promise
wo du es kannstsleep.catch
.setTimeout
Rückruf, und dernew Promise
Rückruf wurde lange durchgeführt. Es wird in den globalen Kontext sprudeln und als unbehandelte Ausnahme ausgelöst.Wenn Sie dieselbe Syntax verwenden möchten, wie
setTimeout
Sie eine Hilfsfunktion wie diese schreiben können:Sie können es dann so nennen:
Ich habe eine Zusammenfassung erstellt: https://gist.github.com/DaveBitter/f44889a2a52ad16b6a5129c39444bb57
quelle
delayRun
wäre hier sinnvoller, da er die Ausführung der Rückruffunktion um X Sekunden verzögert. Kein sehr erwartetes Beispiel, IMO.quelle
Der folgende Code funktioniert in Chrome und Firefox und möglicherweise in anderen Browsern.
Aber in Internet Explorer bekomme ich einen Syntaxfehler für die
"(resolve **=>** setTimeout..."
quelle
Aus Dave 's Antwort inspiriert
Grundsätzlich wird ein
done
Rückruf übergeben, um nach Abschluss des Vorgangs aufzurufen.So benutze ich es:
quelle
Dies ist meine Version mit NodeJS jetzt im Jahr 2020 in AWS Labdas
quelle
Dies ist eine schnellere Lösung für Einzeiler.
Hoffe das wird helfen.
quelle
await setTimeout(()=>{console.log('first')}, 200); console.log ('second')
druckt zweite dann zuerstvar test = async () => { await setTimeout(()=>{console.log('first')}, 1000); console.log ('second') }
Ich habe das Timeout verlängert, um seine Nützlichkeit zu demonstrieren.