javascript - loop - settimeout jquery ejemplo
Combinación de función asíncrona+espera+setTimeout (7)
El siguiente código funciona en Chrome y Firefox y quizás en otros navegadores.
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleep(fn, ...args) {
await timeout(3000);
return fn(...args);
}
Pero en Internet Explorer
"(resolve **=>** setTimeout..."
un error de sintaxis para
"(resolve **=>** setTimeout..."
Estoy tratando de usar las nuevas funciones asíncronas y espero que resolver mi problema ayude a otros en el futuro. Este es mi código que está funcionando:
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
});
}
El problema es que mi ciclo while se ejecuta demasiado rápido y el script envía demasiadas solicitudes por segundo a la API de Google. Por lo tanto, me gustaría construir una función de suspensión que retrase la solicitud. Por lo tanto, también podría usar esta función para retrasar otras solicitudes. Si hay otra forma de retrasar la solicitud, hágamelo saber.
De todos modos, este es mi nuevo código que no funciona. La respuesta de la solicitud se devuelve a la función asincrónica anónima dentro de setTimeout, pero simplemente no sé cómo puedo devolver la respuesta a la función de suspensión resp. a la función inicial 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);
}
Ya he probado algunas opciones: almacenar la respuesta en una variable global y devolverla desde la función de suspensión, devolución de llamada dentro de la función anónima, etc.
Esta es una solución más rápida en una sola línea.
Espero que esto ayude.
// WAIT FOR 200 MILISECONDS TO GET DATA //
await setTimeout(()=>{}, 200);
La forma rápida en línea
await new Promise(resolve => setTimeout(resolve, 1000));
Si desea utilizar el mismo tipo de sintaxis que
setTimeout
, puede escribir una función auxiliar como esta:
const setAsyncTimeout = (cb, timeout = 0) => new Promise(resolve => {
setTimeout(() => {
cb();
resolve();
}, timeout);
});
Luego puede llamarlo así:
const doStuffAsync = async () => {
await setAsyncTimeout(() => {
// Do stuff
}, 1000);
await setAsyncTimeout(() => {
// Do more stuff
}, 500);
await setAsyncTimeout(() => {
// Do even more stuff
}, 2000);
};
doStuffAsync();
Hice una idea esencial: https://gist.github.com/DaveBitter/f44889a2a52ad16b6a5129c39444bb57
Su función de
sleep
no funciona porque
setTimeout
no
setTimeout
(¿todavía?) Una promesa que podría
await
.
Tendrá que prometerlo manualmente:
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleep(fn, ...args) {
await timeout(3000);
return fn(...args);
}
Por cierto, para ralentizar su ciclo, probablemente no desee utilizar una función de
sleep
que tome una devolución de llamada y la difiera de esta manera.
Prefiero recomendar hacer algo como
while (goOn) {
// other code
var [parents] = await Promise.all([
listFiles(nextPageToken).then(requestParents),
timeout(5000)
]);
// other code
}
lo que permite que el cálculo de los
parents
tome al menos 5 segundos.
setTimeout
no es una función
async
, por lo que no puede usarla con ES7 async-await.
Pero podría implementar su función de
sleep
usando ES6
Promise
:
function sleep (fn, par) {
return new Promise((resolve) => {
// wait 3s before calling fn(par)
setTimeout(() => resolve(fn(par)), 3000)
})
}
Entonces podrá utilizar esta nueva función de
sleep
con ES7 async-await:
var fileList = await sleep(listFiles, nextPageToken)
Tenga en cuenta
que solo estoy respondiendo su pregunta sobre la combinación de ES7 async /
setTimeout
con
setTimeout
, aunque puede que no ayude a resolver su problema al enviar demasiadas solicitudes por segundo.
Actualización: las versiones modernas de node.js tienen una implementación de tiempo de espera asíncrono util.promisify , accesible a través de util.promisify helper:
const {promisify} = require(''util'');
const setTimeoutAsync = promisify(setTimeout);
Desde el Nodo 7.6
, puede combinar las funciones de la función
promisify
del módulo utils con
setTimeout()
.
Node.js
const sleep = require(''util'').promisify(setTimeout)
Javascript
const sleep = m => new Promise(r => setTimeout(r, m))
Uso
(async () => {
console.time("Slept for")
await sleep(3000)
console.timeEnd("Slept for")
})()