Búsqueda de sitios web

javascript - Usando setTimeout en cadena de promesas


Aquí estoy tratando de entender las promesas. Aquí, en la primera solicitud, obtengo un conjunto de enlaces. Y en la siguiente solicitud, obtengo el contenido del primer enlace. Pero quiero hacer una pausa antes de devolver el siguiente objeto de promesa. Así que uso setTimeout en ello. Pero me da el siguiente error JSON (sin setTimeout() funciona perfectamente)

SyntaxError: JSON.parse: carácter inesperado en la línea 1 columna 1 de los datos JSON

Me gustaría saber por qué falla? :

let globalObj={};
function getLinks(url){
    return new Promise(function(resolve,reject){
       
       let http = new XMLHttpRequest();
       http.onreadystatechange = function(){
            if(http.readyState == 4){
              if(http.status == 200){
                resolve(http.response);
              }else{
                reject(new Error());
              }
            }           
       }
       http.open("GET",url,true);
       http.send();
    });
}

getLinks('links.txt').then(function(links){
    let all_links = (JSON.parse(links));
    globalObj=all_links;

    return getLinks(globalObj["one"]+".txt");

}).then(function(topic){
    
    
    writeToBody(topic);
    setTimeout(function(){
         return getLinks(globalObj["two"]+".txt"); // without setTimeout it works fine 
         },1000);
});

Respuesta #1

Para mantener la cadena de promesas en funcionamiento, no puedes usar setTimeout() de la manera en que lo hiciste porque no estás devolviendo una promesa desde el manejador .then(), sino que la estás devolviendo desde el callback de setTimeout(), lo cual no te sirve de nada.

En su lugar, puedes hacer una pequeña función de retraso simple como esta:

function delay(t, val) {
    return new Promise(resolve => setTimeout(resolve, t, val));
}

Y luego úsalo así:

getLinks('links.txt').then(function(links){
    let all_links = (JSON.parse(links));
    globalObj=all_links;

    return getLinks(globalObj["one"]+".txt");

}).then(function(topic){
    writeToBody(topic);
    // return a promise here that will be chained to prior promise
    return delay(1000).then(function() {
        return getLinks(globalObj["two"]+".txt");
    });
});

Aquí estás devolviendo una promesa desde el manejador .then() y por lo tanto se encadena apropiadamente.


También puedes añadir un método de retraso al objeto Promise y luego usar directamente un método .delay(x) en tus promesas de esta manera:

function delay(t, val) {
    return new Promise(resolve => setTimeout(resolve, t, val));
}

Promise.prototype.delay = function(t) {
    return this.then(function(val) {
        return delay(t, val);
    });
}


Promise.resolve("hello").delay(500).then(function(val) {
    console.log(val);
});

Respuesta #2

.then(() => new Promise((resolve) => setTimeout(resolve, 15000)))

ACTUALIZACIÓN :

cuando necesito dormir en una función asíncrona lanzo en

await new Promise(resolve => setTimeout(resolve, 1000))

Respuesta #3

La versión más corta de la respuesta en ES6:

const delay = t => new Promise(resolve => setTimeout(resolve, t));

Y luego puedes hacer:

delay(3000).then(() => console.log('Hello'));

Respuesta #4

Desde la versión v15 de Node, puedes usar la API de promesas de temporizadores

ejemplo del documento:

import { setTimeout } from 'timers/promises'

const res = await setTimeout(100, 'result')

console.log(res)  // Prints 'result'

Respuesta #5

Si estás dentro de un bloque .then() y quieres ejecutar un settimeout()

            .then(() => {
                console.log('wait for 10 seconds . . . . ');
                return new Promise(function(resolve, reject) { 
                    setTimeout(() => {
                        console.log('10 seconds Timer expired!!!');
                        resolve();
                    }, 10000)
                });
            })
            .then(() => {
                console.log('promise resolved!!!');

            })

la salida será como se muestra a continuación

wait for 10 seconds . . . .
10 seconds Timer expired!!!
promise resolved!!!

¡Feliz programación!

Artículos relacionados