Sei es ein ES6-Versprechen oder ein Bluebird-Versprechen, Q-Versprechen usw.
Wie teste ich, ob ein Objekt ein Versprechen ist?
Wenn es eine .then
-Funktion hat, ist dies die Standardversprechenbibliothek von only.
Die Promises/A + -Spezifikation hat einen Begriff namens then
able, der im Wesentlichen "ein Objekt mit einer then
-Methode" ist. Versprechen werden und sollten irgendetwas mit einer dann-Methode assimilieren. Alle versprochenen Implementierungen, die Sie erwähnt haben, tun dies.
Wenn wir uns die Spezifikation ansehen :
2.3.3.3 Wenn
then
eine Funktion ist, rufen Sie sie mit x als diesem, dem ersten Argument resolPromise und dem zweiten Argument rejectPromise auf
Es erklärt auch die Gründe für diese Entwurfsentscheidung:
Diese Behandlung von
then
ables ermöglicht versprechende Implementierungen zur Interoperabilität, sofern sie eine Promises/A + -konformethen
-Methode verfügbar machen. Promises/A + -Implementierungen können auch nichtkonforme Implementierungen mit vernünftigen Methoden "assimiliert" werden.
Sie sollten nicht - stattdessen Promise.resolve(x)
(Q(x)
in Q) aufrufen, um always jeden Wert oder eine externe then
able in ein vertrauenswürdiges Versprechen umzuwandeln. Es ist sicherer und einfacher, als diese Prüfungen selbst durchzuführen.
Sie können es immer durch die Testsuite : D ausführen
Die Überprüfung, ob ein Versprechen unnötig ist, macht den Code unnötig kompliziert. Verwenden Sie einfach Promise.resolve
.
Promise.resolve(valueOrPromiseItDoesntMatter).then(function(value) {
})
Hier ist meine ursprüngliche Antwort, die seitdem in der Spezifikation ratifiziert ist, um ein Versprechen zu erhalten:
Promise.resolve(obj) == obj
Dies funktioniert, weil der Algorithmus explizit verlangt, dass Promise.resolve
genau das übergebene Objekt zurückgibt, wenn und nur dann, wenn durch die Definition der Spezifikation ein Versprechen ist.
Ich habe hier eine andere Antwort, die das immer gesagt hat, aber ich habe sie in etwas anderes geändert, als es zu dieser Zeit nicht mit Safari funktionierte. Das war vor einem Jahr, und das funktioniert jetzt auch in Safari zuverlässig.
Ich hätte meine ursprüngliche Antwort bearbeitet, mit der Ausnahme, dass dies falsch war, da inzwischen mehr Menschen für die geänderte Lösung gestimmt haben als das Original. Ich glaube, das ist die bessere Antwort, und ich hoffe, Sie stimmen zu.
Update: Dies ist nicht mehr die beste Antwort. Bitte wählen Sie stattdessen meine andere Antwort .
obj instanceof Promise
sollte es tun. Beachten Sie, dass dies möglicherweise nur mit nativen es6-Versprechen zuverlässig funktioniert.
Wenn Sie ein Shim, eine Versprechungsbibliothek oder etwas anderes verwenden, das vorgibt, versprechend zu sein, kann es sinnvoller sein, auf "Thenable" (alles mit einer .then
-Methode) zu testen, wie in den anderen Antworten hier gezeigt.
if (typeof thing.then === 'function') {
// probably a promise
} else {
// definitely not a promise
}
Um zu sehen, ob das angegebene Objekt ein native ES6 Promise ist, können wir dieses Prädikat verwenden:
function isPromise(value) {
return value && Object.prototype.toString.call(value) === "[object Promise]";
}
Call
ing toString
direkt aus Object.prototype
gibt eine native Stringdarstellung zurück des angegebenen Objekttyps, die in unserem Fall "[object Promise]"
ist. Dies stellt sicher, dass das angegebene Objekt
toString
-Methode des angegebenen Objekts.instanceof
oder isPrototypeOf
.Hier ist das Code-Formular https://github.com/ssnau/xkit/blob/master/util/is-promise.js
!!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
wenn ein Objekt eine then
-Methode hat, sollte es als Promise
behandelt werden.
Falls Sie TypeScript verwenden, möchte ich hinzufügen, dass Sie die Funktion "Typ Prädikat" verwenden können. Sie sollten nur die logische Überprüfung in eine Funktion einschließen, die x is Promise<any>
zurückgibt, und Sie müssen keine Typumwandlungen durchführen. Unten in meinem Beispiel ist c
entweder ein Versprechen oder einer meiner Typen, die ich durch Aufruf der c.fetch()
-Methode in ein Versprechen umwandeln möchte.
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;
}
Weitere Informationen: https://www.typescriptlang.org/docs/handbook/advanced-types.html
Wenn Sie sich in einer asynchronen Methode befinden, können Sie dies tun und Mehrdeutigkeiten vermeiden.
async myMethod(promiseOrNot){
const theValue = await promiseOrNot()
}
Wenn die Funktion ein Versprechen zurückgibt, wird sie den aufgelösten Wert abwarten und zurückgeben. Wenn die Funktion einen Wert zurückgibt, wird dieser als aufgelöst behandelt.
Wenn die Funktion heute kein Versprechen zurückgibt, morgen jedoch eines zurückgibt oder für asynchron erklärt wird, sind Sie zukunftssicher.
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));
});
Keine Antwort auf die gesamte Frage, aber ich denke, es ist erwähnenswert, dass in Node.js 10 eine neue util-Funktion namens isPromise
hinzugefügt wurde, die prüft, ob ein Objekt ein natives Promise ist oder nicht:
const utilTypes = require('util').types
const b_Promise = require('bluebird')
utilTypes.isPromise(Promise.resolve(5)) // true
utilTypes.isPromise(b_Promise.resolve(5)) // false
So erkennt graphql-js package Versprechen:
function isPromise(value) {
return Boolean(value && typeof value.then === 'function');
}
value
ist der Rückgabewert Ihrer Funktion. Ich verwende diesen Code in meinem Projekt und habe bisher kein Problem.