Cuál es la diferencia entre:
new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return "bbb";
  })
  .then(function(result) {
    console.log(result);
  });y esto:
new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return Promise.resolve("bbb");
  })
  .then(function(result) {
    console.log(result);
  });Pregunto ya que obtengo un comportamiento diferente Uso del servicio Angular y $ http con el encadenamiento .then (). Demasiado código, por lo tanto, primero el ejemplo anterior.
                    
                        javascript
                                angularjs
                                promise
                                q
                                
                    
                    
                        spirytus
fuente
                
                fuente

Promise.resolve()en el segundo ejemplo es innecesario.thencontrolador, de hecho, es un aspecto clave de la especificación de promesas que puede hacer eso.thens anidados arbitrariamente : el término 'otros idiomas' para esto es quethenes amapy aflatMap.new Promise((res, rej) => { return fetch('//google.com').then(() => { return "haha"; }) }).then((result) => alert(result));este código simplemente se bloqueará (no se resolverá para siempre). Pero si cambioreturn "haha";a,return res("haha");entonces funcionará y alertará a "jaja". ¿El fetch (). Then () ya envolvió "jaja" en una promesa resuelta?Respuestas:
La regla es, si la función que está en el
thencontrolador devuelve un valor, la promesa se resuelve / rechaza con ese valor, y si la función devuelve una promesa, lo que sucede es que la siguientethencláusula será lathencláusula de la promesa que la función devolvió , por lo tanto, en este caso, el primer ejemplo cae a través de la secuencia normal de losthensvalores e imprime como se podría esperar, en el segundo ejemplo, el objeto de promesa que se devuelve cuando lo hacePromise.resolve("bbb")es elthenque se invoca al encadenar (para todos los efectos). La forma en que realmente funciona se describe a continuación con más detalle.Citando de las promesas / especificaciones A +:
La clave para notar aquí es esta línea:
fuente
thencontrolador devuelve una promesa. +1 para la referencia de especificaciones.[[Resolve]]se llama tanto enthenvalores como en valores, por lo que esencialmente envuelve un valor con la promesa, por lo quereturn "aaa"es el mismoreturn Promise.resolve("aaa")yreturn Promise.resolve("aaa")es el mismoreturn Promise.resolve(Promise.resolve("aaa")), ya que la resolución es idempotente al llamarlo a un valor más que una vez tiene el mismo resultado."aaa"yreturn Promise.resolve("aaa")son intercambiables enthenables en cualquier caso?En términos simples, dentro de una
thenfunción de controlador:A) Cuando
xes un valor (número, cadena, etc.):return xes equivalente areturn Promise.resolve(x)throw xes equivalente areturn Promise.reject(x)B) Cuándo
xes una promesa que ya está liquidada (ya no está pendiente):return xes equivalente areturn Promise.resolve(x), si la promesa ya se resolvió.return xes equivalente areturn Promise.reject(x), si la promesa ya fue rechazada.C) Cuando
xhay una promesa pendiente:return xdevolverá una Promesa pendiente y se evaluará en el siguientethen.Lea más sobre este tema en los documentos Promise.prototype.then () .
fuente
Ambos ejemplos deberían comportarse más o menos igual.
Un valor devuelto dentro de un
then()controlador se convierte en el valor de resolución de la promesa devuelta de esothen(). Si el valor devuelto dentro del.thenes una promesa, la promesa devuelta porthen()"adoptará el estado" de esa promesa y se resolverá / rechazará tal como lo hace la promesa devuelta.En su primer ejemplo, regresa
"bbb"en el primerthen()controlador, por lo que"bbb"se pasa al siguientethen()controlador.En su segundo ejemplo, devuelve una promesa que se resuelve de inmediato con el valor
"bbb", por lo que"bbb"se pasa al siguientethen()controlador. (ElPromise.resolve()aquí es extraño).El resultado es el mismo.
Si puede mostrarnos un ejemplo que en realidad exhibe un comportamiento diferente, podemos decirle por qué sucede eso.
fuente
Promise.resolve();vsreturn;?undefinedlugar de"bbb".Ya tienes una buena respuesta formal. Pensé que debería agregar uno corto.
Las siguientes cosas son idénticas a las promesas / promesas A + :
Promise.resolve(en su caso angular, eso es$q.when)new $q.thendevolución de llamada.Por lo tanto, los siguientes son idénticos para una promesa o un valor simple X:
Y no es sorprendente, la especificación de promesas se basa en el Procedimiento de resolución de promesas que permite una fácil interoperación entre bibliotecas (como $ q y promesas nativas) y hace que su vida sea más fácil en general. Cada vez que se produce una resolución prometedora, se produce una resolución que crea coherencia general.
fuente
Promise.resolve().then(function(){ return x; });? Encontré un recorte haciendo algo similar (llamó una función dentro delthenbloque). Pensé que era más o menos como hacer un tiempo de espera, pero es un poco más rápido. jsben.ch/HIfDowithbloque sobre un objeto o proxy con unxdescriptor de acceso de propiedad que arroja una excepción. En ese caso, Promise.resolve (x) causaría un error arrojado peroPromise.resolve().then(function(){ return x; });sería una promesa rechazada ya que el error es arrojado en athen).if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }. Aquí la promesa no está asignada, entonces, ¿cuál es el punto? Un tiempo de espera tendría (más o menos) el mismo efecto, ¿o no?La única diferencia es que estás creando una promesa innecesaria cuando lo haces
return Promise.resolve("bbb"). Devolver una promesa de unonFulfilled()controlador inicia la resolución de la promesa . Así es como funciona el encadenamiento de promesas .fuente