sincronas promesas funciones entre ejemplos ejecucion diferencia controlar asincrona javascript promise q bluebird es6-promise

javascript - promesas - innerhtml



¿Cómo puedo saber si un objeto es una promesa? (14)

Cómo decide una biblioteca de promesas

Si tiene una función .then , esa es la única promesa estándar que usan las bibliotecas.

La especificación Promises / A + tiene una noción llamada then capaz que es básicamente "un objeto con un método de then ". Las promesas deben y deben asimilar cualquier cosa con un método de entonces. Toda la implementación de promesa que ha mencionado hace esto.

Si nos fijamos en la specification :

2.3.3.3 si then es una función, llámela con x como esto, primer argumento resolvePromise y segundo argumento acceptPromise

También explica la justificación de esta decisión de diseño:

Este tratamiento de ables permite que las implementaciones de promesas interoperen, siempre que expongan un método de Promesas / A + que cumpla then . También permite que las implementaciones de Promises / A + "asimilen" implementaciones no conformes con métodos razonables.

Cómo debes decidir

No debería, en su lugar, llamar a Promise.resolve(x) ( Q(x) en Q) que siempre convertirá cualquier valor o externo que pueda convertirse en una promesa confiable. Es más seguro y fácil que realizar estas comprobaciones usted mismo.

realmente necesita estar seguro?

Siempre puede ejecutarlo a través del conjunto de pruebas : D

Ya sea una promesa ES6 o una promesa Bluebird, Q Promise, etc.

¿Cómo pruebo para ver si un objeto dado es una promesa?



Aquí está mi respuesta original, que desde entonces ha sido ratificada en la especificación como la forma de probar una promesa:

Promise.resolve(obj) == obj

Esto funciona porque el algoritmo exige explícitamente que Promise.resolve debe devolver el objeto exacto pasado si y solo si es una promesa según la definición de la especificación.

Tengo otra respuesta aquí, que solía decir esto, pero la cambié a otra cuando no funcionaba con Safari en ese momento. Eso fue hace un año, y ahora funciona de manera confiable incluso en Safari.

Habría editado mi respuesta original, excepto que se sentía mal, dado que ahora más personas han votado por la solución alterada en esa respuesta que la original. Creo que esta es la mejor respuesta, y espero que esté de acuerdo.


Así es como el paquete graphql-js detecta promesas:

it(''should return a promise'', function() { var result = testedFunctionThatReturnsPromise(); expect(result).toBeDefined(); // 3 slightly different ways of verifying a promise expect(typeof result.then).toBe(''function''); expect(result instanceof Promise).toBe(true); expect(result).toBe(Promise.resolve(result)); });

value es el valor devuelto de su función. Estoy usando este código en mi proyecto y no tengo ningún problema hasta ahora.


Comprobar si algo es prometedor complica innecesariamente el código, solo use Promise.resolve

Promise.resolve(valueOrPromiseItDoesntMatter).then(function(value) { })


Después de buscar una forma confiable de detectar funciones asincrónicas o incluso promesas , terminé usando la siguiente prueba:

() => fn.constructor.name === ''Promise'' || fn.constructor.name === ''AsyncFunction''


ES6:

const promise = new Promise(resolve => resolve(''olá'')); console.log(promise.toString().includes(''Promise'')); //true


En caso de que esté utilizando Typecript , me gustaría agregar que puede usar la función "predicado de tipo". Solo debe envolver la verificación lógica en una función que devuelve x is Promise<any> y no necesitará hacer typecasts. A continuación, en mi ejemplo, c es una promesa o uno de mis tipos que quiero convertir en una promesa llamando al método c.fetch() .

export function toPromise(c: Container<any> | Promise<any>): Promise<any> { if (c == null) return Promise.resolve(); return isContainer(c) ? c.fetch() : c; } export function isContainer(val: Container<any> | Promise<any>): val is Container<any> { return val && (<Container<any>>val).fetch !== undefined; } export function isPromise(val: Container<any> | Promise<any>): val is Promise<any> { return val && (<Promise<any>>val).then !== undefined; }

Más información: https://www.typescriptlang.org/docs/handbook/advanced-types.html


No es una respuesta a la pregunta completa, pero creo que vale la pena mencionar que en Node.js 10 se agregó una nueva función de isPromise llamada isPromise que verifica si un objeto es una Promesa nativa o no:

const utilTypes = require(''util'').types const b_Promise = require(''bluebird'') utilTypes.isPromise(Promise.resolve(5)) // true utilTypes.isPromise(b_Promise.resolve(5)) // false


Para ver si el objeto dado es una promesa ES6 , podemos hacer uso de este predicado:

function isPromise(p) { return p && Object.prototype.toString.call(p) === "[object Promise]"; }

Call a toString directamente desde el Object.prototype devuelve una representación de cadena nativa del tipo de objeto dado que es "[object Promise]" en nuestro caso. Esto asegura que el objeto dado

  • Omite falsos positivos como ..:
    • Tipo de objeto autodefinido con el mismo nombre de constructor ("Promesa").
    • Método de escritura automática toString del objeto dado.
  • Funciona en múltiples contextos de entorno (por ejemplo, iframes) en contraste con instanceof o isPrototypeOf .

Sin embargo, cualquier objeto host particular, que tenga su etiqueta modificada a través de Symbol.toStringTag , puede devolver "[object Promise]" . Este puede ser el resultado deseado o no dependiendo del proyecto (por ejemplo, si hay una implementación personalizada de Promise).

Para ver si el objeto es de una Promesa ES6 nativa , podemos usar:

function isNativePromise(p) { return p && typeof p.constructor === "function" && Function.prototype.toString.call(p.constructor).replace(//(.*/)/, "()") === Function.prototype.toString.call(/*native object*/Function) .replace("Function", "Promise") // replacing Identifier .replace(//(.*/)/, "()"); // removing possible FormalParameterList }

De acuerdo con this y esta sección de la especificación, la representación de cadena de la función debe ser:

" Identificador de función ( FormalParameterList opt ) { FunctionBody }"

que se maneja en consecuencia arriba. FunctionBody es [native code] en todos los principales navegadores.

MDN: Function.prototype.toString

Esto también funciona en múltiples contextos de entorno.


Si utiliza un método asíncrono, puede hacerlo y evitar cualquier ambigüedad.

async myMethod(promiseOrNot){ const theValue = await promiseOrNot() }

Si la función devuelve la promesa, esperará y volverá con el valor resuelto. Si la función devuelve un valor, se tratará como resuelto.

Si la función no devuelve una promesa hoy, pero mañana devuelve una o se declara asíncrona, estará preparado para el futuro.


Actualización: esta ya no es la mejor respuesta. Por favor vote mi otra respuesta en su lugar.

obj instanceof Promise

Deberías hacerlo. Tenga en cuenta que esto solo puede funcionar de manera confiable con las promesas nativas de es6.

Si está utilizando una cuña, una biblioteca de promesas o cualquier otra cosa que pretenda ser como una promesa, entonces puede ser más apropiado probar un "thenable" (cualquier cosa con un método .then ), como se muestra en otras respuestas aquí.


function isPromise(value) { return Boolean(value && typeof value.then === ''function''); }


if (typeof thing.then === ''function'') { // probably a promise } else { // definitely not a promise }