¿Cómo puedo acceder al valor de una promesa?

7 minutos de lectura

avatar de usuario de temporary_user_name
nombre_de_usuario_temporal

Estoy viendo este ejemplo de la documentación de Angular para $q, pero creo que esto probablemente se aplica a las promesas en general. El siguiente ejemplo se copia textualmente de su documentación con su comentario incluido:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1

No tengo claro cómo funciona esto. si puedo llamar .then() sobre el resultado de la primera .then()encadenándolos, que sé que puedo, entonces promiseB es un objeto de promesa, de tipo Object. No es un Number. Entonces, ¿qué quieren decir con “su valor será el resultado de la promesa A incrementada en 1”?

¿Se supone que debo acceder a eso como promiseB.value ¿o algo así? ¿Cómo puede la devolución de llamada exitosa devolver una promesa Y devolver “resultado + 1”? me estoy perdiendo algo

  • Hice una pregunta relacionada: ¿Por qué Promise no tiene una función get ()?

    – roland

    28 de julio de 2017 a las 16:25


  • ¿Responde esto a tu pregunta? ¿Cómo devuelvo la respuesta de una llamada asíncrona?

    – Mono hereje

    27 de febrero de 2020 a las 22:40

Avatar de usuario de Nachshon Schwartz
Nachshon Schwartz

promiseA‘s then función devuelve una nueva promesa (promiseB) que se resuelve inmediatamente después promiseA se resuelve, su valor es el valor de lo que se devuelve de la función de éxito dentro promiseA.

En este caso promiseA se resuelve con un valor – result y luego resuelve inmediatamente promiseB con el valor de result + 1.

Acceder al valor de promiseB se hace de la misma manera que accedimos al resultado de promiseA.

promiseB.then(function(result) {
    // here you can use the result of promiseB
});

A partir de ECMAScript 2016 (ES7, 2016), async/await es estándar en JavaScript, lo que permite una sintaxis alternativa al enfoque descrito anteriormente. Ahora puedes escribir:

let result = await functionThatReturnsPromiseA();
result = result + 1;

Ahora no hay promesaB, porque hemos desenvuelto el resultado de promesaA usando awaity puede trabajar con él directamente.

Sin embargo, await sólo se puede utilizar dentro de un async función. Entonces, para alejar un poco, lo anterior debería estar contenido así:

async function doSomething() {
    let result = await functionThatReturnsPromiseA();
    return result + 1;
}

Y, para mayor claridad, el valor de retorno de la función doSomething en este ejemplo sigue siendo una promesa, porque las funciones asíncronas devuelven promesas. Entonces, si quisiera acceder a ese valor de retorno, tendría que hacer result = await doSomething(), que solo puede hacer dentro de otra función asíncrona. Básicamente, solo en un contexto asíncrono principal puede acceder directamente al valor producido desde un contexto asíncrono secundario.

  • Las promesas son teóricamente sus propios objetos. contienen un resultado al que se puede acceder a través de la función de éxito de la promesa.

    – Nachshon Schwartz

    08/04/2015 a las 13:53


  • Entonces, si desea trabajar con el valor de retorno de la devolución de llamada asíncrona de una promesa, debe hacerlo dentro de otra devolución de llamada asíncrona. Tiene sentido. Había estado buscando una manera de obtener un valor de retorno primitivo definitivo, pero supongo que desafiaría la razón dado el contexto.

    – nombre_de_usuario_temporal

    08/04/2015 a las 14:05


  • @Aerovistae en realidad, ES6 presenta generadores que lo hacen posible y ES7 presenta funciones asíncronas, las cuales le brindan azúcar de sintaxis sobre promesas que hacen que parezca un código síncrono (ejecutando una máquina de estado en segundo plano), así que agárrese fuerte 🙂

    – Benjamin Grünbaum

    9 de abril de 2015 a las 8:56

  • ¿Qué significa inmediatamente resuelto en la primera línea de la respuesta?

    – EternalObserver

    1 de noviembre de 2021 a las 12:26

  • Envolver una promesa en una función asíncrona sigue siendo asíncrono. ¿Cómo se puede obtener inmediatamente el resultado de una promesa resuelta?

    – Suncat2000

    14 de junio a las 13:58

avatar de usuario de pixelbits
bits de píxeles

Cuando se resuelve/rechaza una promesa, llamará a su controlador de éxito/error:

var promiseB = promiseA.then(function(result) {
   // do something with result
});

los then El método también devuelve una promesa: promiseB, que será resuelta/rechazada dependiendo del valor de retorno del controlador de éxito/error de promiseA.

Hay tres valores posibles que pueden devolver los controladores de éxito/error de la promesa A que afectarán el resultado de la promesa B:

  1. No devuelve nada → PromiseB se resuelve inmediatamente, y undefined se pasa al controlador de éxito de promiseB
  2. Devuelve un valor → PromiseB se resuelve inmediatamente y el valor se pasa al controlador de éxito de promiseB
  3. Devolver una promesa → Cuando se resuelva, se resolverá la promesaB. Cuando se rechaza, se rechazará la promesa B. El valor pasado al controlador de la promesa B será el resultado de la promesa.

Armado con este entendimiento, puede dar sentido a lo siguiente:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

La llamada entonces devuelve promesaB inmediatamente.

Cuando se resuelve la promesaA, pasará el resultado al controlador de éxito de la promesaA.

Dado que el valor de retorno es el resultado de la promesa A + 1, el controlador de éxito está devolviendo un valor (opción 2 anterior), por lo que la promesa B se resolverá de inmediato y el controlador de éxito de la promesa B recibirá el resultado de la promesa A + 1.

Avatar de usuario de Zeus Lalkaka
Zeus Lalkaka

La respuesta de pixelbits es correcta, y siempre debes usar .then() para acceder al valor de una promesa en el código de producción.

Sin embargo, hay una manera de acceder al valor de la promesa directamente después de que se haya resuelto mediante el uso de la siguiente interna no admitida Nodo.js Unión:

process.binding('util').getPromiseDetails(myPromise)[1]

ADVERTENCIA: process.binding nunca se pensó para usarse fuera del núcleo de Node.js y el equipo central de Node.js está buscando activamente desaprobarlo

  • Es raro encontrar una respuesta que se supone que no debe usarse (:

    – mteam88

    9 de agosto a las 1:16

avatar de usuario de harishr
harishr

los .then función de promiseB recibe lo que se devuelve de la .then función de la promesa A.

Aquí, promiseA devuelve un número, que estará disponible como el number parámetro en el éxito función de la promesa B. Que luego se incrementará en 1.

Avatar de usuario de Jason Cust
jason cust

Analizar el comentario de manera un poco diferente a su comprensión actual podría ayudar:

// promiseB will be resolved immediately after promiseA is resolved

Esto establece que promiseB es una promesa, pero se resolverá inmediatamente después promiseA esta resuelto. Otra forma de ver esto significa que promiseA.then() devuelve una promesa que se asigna a promiseB.

// and its value will be the result of promiseA incremented by 1

Esto significa que el valor que promiseA resuelto es el valor que promiseB recibirá como su valor de devolución de llamada exitosa:

promiseB.then(function (val) {
  // val is now promiseA's result + 1
});

Avatar de usuario de Peter Mortensen
Pedro Mortensen

Hay algunas buenas respuestas anteriores y aquí está el ES6 versión de la función de flecha:

var something = async() => {
    let result = await functionThatReturnsPromiseA();
    return result + 1;
}

Avatar de usuario de Peter Mortensen
Pedro Mortensen

En realidad, desde el indicador interactivo (Node.js), uno puede simplemente “esperar”:

> y = new Promise((resolve, reject) => resolve(23));
Promise {
   23,
   [Symbol(async_id_symbol)]: 10419,
   [Symbol(trigger_async_id_symbol)]: 5,
   [Symbol(destroyed)]: { destroyed: false }
}
> v = await y;
23

Esto es útil cuando se experimenta en el REEMPLAZAR.

No puedes hacer esto en una función “ordinaria”:

> function foo() { let z = await y; return z; }
Uncaught SyntaxError:
Unexpected token 'y'

Puede hacer esto en una “función asíncrona”, pero eso lo deja con una promesa, no el valor que desea:

> async function foo() { let z = await y; return z; }
undefined
> foo()
Promise {
  <pending>,
  [Symbol(async_id_symbol)]: 10571,
  [Symbol(trigger_async_id_symbol)]: 5,
  [Symbol(destroyed)]: { destroyed: false }
}

  • Pero con la función async-await, al menos sabe que el valor está disponible de inmediato y puede usarse en un .then() cláusula sobre la promesa devuelta.

    – Suncat2000

    16 de mayo a las 15:11

¿Ha sido útil esta solución?