Obtener el valor de retorno de setTimeout [duplicado]

95

Solo quiero obtener el valor de retorno, setTimeoutpero ¿lo que obtengo es un formato de texto completo de la función?

function x () {
    setTimeout(y = function () {
        return 'done';
    }, 1000);
    return y;
}

console.log(x());
8
  • su sintaxis es así, solo devolverá la función. 24 de julio de 2014 a las 8:36
  • ¿Quieres que te devuelvan "listo"? ¿Cómo puede devolver un resultado de función, que se llamará 1000 ms más tarde? 24 de julio de 2014 a las 8:37
  • 1
    Los tiempos de espera son asincrónicos, por lo que no puede regresar de ellos. (bueno, puedes, pero el valor de retorno no va a ninguna parte) 24 de julio de 2014 a las 8:37
  • es mejor obtener una devolución de llamada en función xy llamar a esa función con listo. 24 de julio de 2014 a las 8:38
  • 2
    const x = async (waitMs) => new Promise((resolve) => setTimeout(() => resolve('done'), waitMs)); console.log(await x(1000)); 20 abr.20 a las 16:35
116

Necesita usar Promesas para esto. Están disponibles en ES6 pero se pueden rellenar con polietileno con bastante facilidad :

function x() {
   var promise = new Promise(function(resolve, reject) {
     window.setTimeout(function() {
       resolve('done!');
     });
   });
   return promise;
}

x().then(function(done) {
  console.log(done); // --> 'done!'
});

Con async/ awaiten ES2017 se vuelve mejor si está dentro de una asyncfunción:

async function() {
  const result = await x();
  console.log(result); // --> 'done!';
}
2
  • en realidad, doneen mi ejemplo era una promesa que debe devolverse dentro de un setTimeout ... porque no puedo obtener el deferred.resolve () devuelto dentro de setTimeout. ¿cómo sería? gracias 24/07/2014 a las 9:33
  • 4
    ¿Puede publicar un ejemplo más claro de su código en la pregunta? 24/07/2014 a las 11:11
22

No puede obtener un valor de retorno de la función a la que pasa setTimeout.

La función que llamó setTimeout( xen su ejemplo) terminará de ejecutarse y regresará antes de que setTimeoutse llame a la función a la que pasa .

Lo que sea que desee hacer con el valor que obtenga, debe hacerlo desde la función a la que pasa setTimeout.

En su ejemplo, eso se escribiría como:

function x () {
    setTimeout(function () {
        console.log("done");
    }, 1000);
}

x();
2
  • 13
    La pregunta pregunta cómo "devolver" un valor. Su función realmente no devuelve nada, sino que ejecuta una función console.log. 14/08/19 a las 7:05
  • 6
    @ kaizer1v - Eso sería porque es imposible devolver el valor (como dediqué a explicar los dos primeros párrafos de la respuesta).
    Quentin
    14 de agosto de 2019 a las 7:58
4

Es mejor recibir una devolución de llamada para la función xy cualquier tarea que desee realizar después de ese tiempo de espera envíe esa devolución de llamada.

function x (callback) {
    setTimeout(function () {
        callback("done");
    }, 1000);
}

x(console.log.bind(console)); //this is special case of console.log
x(alert) 
1
  • 2
    Tenga en cuenta que esto no esperará después de la llamada a la función, por lo que es posible que no suceda. Por ejemplo, agregue process.exit, después de llamar a x y "done" nunca se terminará. 30 oct 2018 a las 8:42
-1

Puede usar una combinación de Promise y setTimeOut como en el siguiente ejemplo

let f1 = function(){
    return new Promise(async function(res,err){
        let x=0;
        let p = new Promise(function(res,err){
            setTimeout(function(){
                x= 1;
                res(x);
            },2000)
        })
        p.then(function(x){
            console.log(x);
            res(x);
        })


    });
}
-6

Creo que quieres tener una bandera para saber si ocurrió el evento o no. setTimeout no devuelve un valor. puede usar una variable para detectar eventos ocurridos o no

var y="notdone";
   setTimeout(function () {
         y="done";
    }, 1000);

Puede acceder a la variable y después de que se agote el tiempo de espera para saber si está hecho o no