Ya sea una promesa ES6 o una promesa Bluebird, Q Promise, etc.
¿Cómo pruebo para ver si un objeto dado es una promesa?
javascript
promise
q
bluebird
es6-promise
el carnero
fuente
fuente

.thenmétodo, pero eso no le diría que lo que tiene es una Promesa definitivamente. Todo lo que sabría en ese momento es que tiene algo que expone un.thenmétodo, como una Promesa..thenmétodo que no sea una Promesa, no se comporte como una Promesa y no tuviera la intención de ser utilizado como una Promesa. Buscar un.thenmétodo solo te dice que si el objeto no tiene un.thenmétodo, entonces no tienes una Promesa. La inversa - que la existencia de unos.thenmedios método que haces tiene una promesa - no es necesariamente cierto..thenmétodo. Sí, eso tiene el potencial de falsos positivos, pero se supone que todas las bibliotecas prometedoras dependen (porque eso es todo en lo que pueden confiar). La única alternativa hasta donde puedo ver es tomar la sugerencia de Benjamin Gruenbaum y ejecutarla a través del conjunto de pruebas de promesa. Pero eso no es práctico para el código de producción real.Respuestas:
Cómo decide una biblioteca de promesas
Si tiene una
.thenfunción, esa es la única promesa estándar que usan las bibliotecas.La especificación Promesas / A + tiene una noción llamada
thencapaz que es básicamente "un objeto con unthenmétodo". Las promesas harán y deberían 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 especificación :
También explica la justificación de esta decisión de diseño:
Cómo deberías decidir
No debería, en su lugar, llamar
Promise.resolve(x)(Q(x)en Q) que siempre convertirá cualquier valor othencapacidad externa 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
fuente
Comprobar si algo es prometedor complica innecesariamente el código, solo use
Promise.resolvefuente
Aquí está mi respuesta original, que desde entonces ha sido ratificada en la especificación como la forma de probar una promesa:
Esto funciona porque el algoritmo exige explícitamente que
Promise.resolvedebe 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 sintió 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.
fuente
===lugar de==?Actualización: esta ya no es la mejor respuesta. Por favor vote mi otra respuesta en su lugar.
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 hacer una prueba para un "thenable" (cualquier cosa con un
.thenmétodo), como se muestra en otras respuestas aquí.fuente
Promise.resolve(obj) == objno funcionará en Safari. Usar en suinstanceof Promiselugar.obj && typeof obj.then == 'function', porque funcionará con todo tipo de promesas y en realidad es la forma recomendada por la especificación y utilizada por las implementaciones / polyfills. Native,Promise.allpor ejemplo, funcionará en todas lasthencapacidades, no solo en otras promesas nativas. También debería tu código. Entoncesinstanceof Promiseno es una buena solución.console.log(typeof p, p, p instanceof Promise);produce este resultado:object Promise { <pending> } false. Como puede ver, es una promesa, ¿y lainstanceof Promiseprueba vuelvefalse?fuente
Para ver si el objeto dado es una promesa ES6 , podemos hacer uso de este predicado:
CallingtoStringdirectamente delObject.prototypedevuelve una representación de cadena nativa del tipo de objeto dado que es"[object Promise]"en nuestro caso. Esto asegura que el objeto dadotoStringMétodo auto-escrito del objeto dado.instanceofoisPrototypeOf.Sin embargo, cualquier objeto host particular , que tenga su etiqueta modificada a través de
Symbol.toStringTag, puede regresar"[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:
De acuerdo con esta y esta sección de la especificación, la representación de cadena de la función debe ser:
que se maneja en consecuencia arriba. El FunctionBody es
[native code]en todos los principales navegadores.MDN:
Function.prototype.toStringEsto también funciona en múltiples contextos de entorno.
fuente
No es una respuesta a la pregunta completa, pero creo que vale la pena mencionar que en Node.js 10
isPromisese agregó una nueva función de utilidad llamada que comprueba si un objeto es una Promesa nativa o no:fuente
Así es como el paquete graphql-js detecta las promesas:
valuees el valor devuelto de su función. Estoy usando este código en mi proyecto y no tengo ningún problema hasta ahora.fuente
Aquí está el formulario de código https://github.com/ssnau/xkit/blob/master/util/is-promise.js
si un objeto con un
thenmétodo, debe tratarse como aPromise.fuente
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 regrese
x is Promise<any>y no necesitará hacer typecasts. A continuación, en mi ejemplo,chay una promesa o uno de mis tipos que quiero convertir en una promesa llamando alc.fetch()método.Más información: https://www.typescriptlang.org/docs/handbook/advanced-types.html
fuente
Si utiliza un método asíncrono, puede hacerlo y evitar cualquier ambigüedad.
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.
fuente
Promise.resolve()fuente
Yo uso esta función como una solución universal:
fuente
Después de buscar una forma confiable de detectar funciones asincrónicas o incluso promesas , terminé usando la siguiente prueba:
fuente
Promisey crea instancias de eso, esta prueba puede fallar. Sin embargo, esto debería funcionar para la mayoría de lo que estás tratando de probar.fn.constructor.name === 'AsyncFunction'está mal, significa que algo es una función asincrónica y no una promesa, tampoco se garantiza que funcione porque la gente puede subclasificar las promesasES6:
fuente
toStringmétodo puede devolver una cadena que incluya"Promise".'NotAPromise'.toString().includes('Promise') === true