Wie kann die Art der Auflösung und Ablehnung des Versprechens in JSDoc angegeben werden?


83

Ich habe einen Code, der ein Versprechungsobjekt zurückgibt, z. B. die Q- Bibliothek für NodeJS.

var Q = require('q');

/**
 * @returns ???
 */
function task(err) {
    return err? Q.reject(new Error('Some error')) : Q.resolve('Some result');
}

Wie dokumentiere ich einen solchen Rückgabewert mit JSDoc?


Ich habe mich über etwas Ähnliches gewundert. Wie dokumentiere ich den Rückgabetyp einer Funktion, die je nach Eingabe und Status der Anwendung mehrere verschiedene Dinge zurückgeben kann?
Hoffmann

Verwenden Sie die Wildcard- Syntax: @returns {*}
Paul Sweatte

Die Wildcard-Syntax ist nicht so spezifisch und hilft nicht.
Arikon

2
@arikon Hilft @returns {ErrorObject|ResultObject}? Die Verwendung der Typbeschreibung "Pipe" ist eine gängige Praxis.
John Doe

3
@ John-Doe Nein, das tut es nicht. Weil die Funktion das Promise-Objekt zurückgibt, nicht nur das Ergebnis oder den Fehler.
Arikon

Antworten:


72

Auch wenn sie in Javascript nicht vorhanden sind, habe ich festgestellt, dass JSdoc "generische Typen" versteht.

So können Sie Ihre benutzerdefinierten Typen definieren und dann verwenden /* @return Promise<MyType> */. Das folgende Ergebnis führt zu einem netten TokenConsume (Token) → {Promise. <Token>} mit einem Link zu Ihrem benutzerdefinierten TokenTyp im Dokument.

/**
 * @typedef Token
 * @property {bool} valid True if the token is valid.
 * @property {string} id The user id bound to the token.
 */

/**
 * Consume a token
 * @param  {string} token [description]
 * @return {Promise<Token>} A promise to the token.
 */
TokenConsume = function (string) {
  // bla bla
}

Es funktioniert sogar mit /* @return Promise<MyType|Error> */oder /* @return Promise<MyType, Error> */.


1
@ Sebastian ja das ist die Idee!
Jillro

Für YUIDoc fand ich diese Werke:@return {Promise|Token}
J Chris A

gute Idee! Ich hatte es geändert zu:@returns {Promise<ForumPost>|Promise<false>|Error}
Przemek Lewandowski

1
Ich mag diese Lösung überhaupt nicht, weil jsdoc das typedef auf eine andere Seite trennt als die Funktion, die es zurückgibt. Außerdem müssen Sie alle auflösbaren Objekttypen benennen. Sie möchten jedoch nur mehrere Werte zurückgeben und in ein Objekt einschließen.
Bob McElrath

2
Update vom Projektbesitzer über die aktuelle Lösung und was für die Veröffentlichung geplant ist github.com/jsdoc3/jsdoc/issues/1197#issuecomment-312948746
Mike Grace

7

Ich neige dazu, einen externen Typ für das Versprechen zu definieren:

/**
* A promise object provided by the q promise library.
* @external Promise
* @see {@link https://github.com/kriskowal/q/wiki/API-Reference}
*/

Jetzt können Sie in der @returnErklärung Ihrer Funktionsdokumentation beschreiben, was mit dem Versprechen passiert:

/**
* @return {external:Promise}  On success the promise will be resolved with 
* "some result".<br>
* On error the promise will be rejected with an {@link Error}.
*/
function task(err) {
    return err? Q.reject(new Error('Some error')) : Q.resolve('Some result');
}

6

Mit JSDoc können Sie auch benutzerdefinierte Typen mit erstellen @typedef. Ich benutze dies ziemlich oft, damit Requisiten / Parameter, die Zeichenfolgen oder Arrays sind, mit einer Beschreibung des Typs verknüpft sind (wie zum Beispiel, als stringich ein typedef erstellt habe, das die für Zeichenfolgen verfügbaren Eingeborenen enthält (siehe das Beispiel JSDoc unten). Sie können einen benutzerdefinierten Typ definieren Dies liegt daran, dass Sie die Objektpunktnotation nicht wie bei @property für Rückgaben verwenden können, um anzugeben, was in der Rückgabe enthalten ist. In Fällen, in denen Sie so etwas wie ein Objekt zurückgeben, können Sie eine Definition erstellen für diesen Typ (' @typedef MyObject) und dann @returns {myObject} Definition of myObject.

Ich würde damit jedoch nicht verrückt werden, da Typen so wörtlich wie möglich sein sollten und Sie Ihre Typen nicht verschmutzen möchten, aber es gibt Fälle, in denen Sie den Typ explizit definieren möchten, um zu dokumentieren, was ist darin (ein gutes Beispiel ist Modernizr ... es gibt ein Objekt zurück, aber Sie haben keine Dokumentation darüber, also erstellen Sie ein benutzerdefiniertes typedef, das detailliert beschreibt, was in dieser Rückgabe enthalten ist).

Wenn Sie diesen Weg nicht gehen müssen, können Sie, wie bereits erwähnt, mithilfe der Pipe mehrere Typen für @param, @property oder @return angeben |.

In Ihrem Fall sollten Sie auch eine dokumentieren, @throwsweil Sie eine werfen new error: * @throws {error} Throws a true new error event when the property err is undefined or not available.

//saved in a file named typedefs.jsdoc, that is in your jsdoc crawl path
/**
    * @typedef string
    * @author me
    * @description A string literal takes form in a sequence of any valid characters. The `string` type is not the same as `string object`.
    * @property {number} length The length of the string
    * @property {number} indexOf The occurence (number of characters in from the start of the string) where a specifc character occurs
    * @property {number} lastIndexOf The last occurence (number of characters in from the end of the string) where a specifc character occurs
    * @property {string|number} charAt Gives the character that occurs in a specific part of the string
    * @property {array} split Allows a string to be split on characters, such as `myString.split(' ')` will split the string into an array on blank spaces
    * @property {string} toLowerCase Transfer a string to be all lower case
    * @property {string} toUpperCase Transfer a string to be all upper case
    * @property {string} substring Used to take a part of a string from a given range, such as `myString.substring(0,5)` will return the first 6 characters
    * @property {string} substr Simialr to `substring`, `substr` uses a starting point, and then the number of characters to continue the range. `mystring.substr(2,8)` will return the characters starting at character 2 and conitnuing on for 8 more characters
    * @example var myString = 'this is my string, there are many like it but this one is HOT!';
    * @example
    //This example uses the string object to create a string...this is almost never needed
    myString = new String('my string');
    myEasierString = 'my string';//exactly the same as what the line above is doing
*/

1
Leider funktioniert dies in PHPStorm nicht, wodurch der Typ im @typedefTag als ungelöst hervorgehoben wird. Ja, duh, ich definiere es genau hier!
David Harkness

Ich werfe keinen Fehler, sondern erstelle seine Instanz, um ihn an Q.reject () zu übergeben
Arikon

6

Derzeit von Jsdoc3 unterstützte Syntax:

/**
 * Retrieve the user's favorite color.
 *
 * @returns {Promise<string>} A promise that contains the user's favorite color
 * when fulfilled.
 */
User.prototype.getFavoriteColor = function() {
     // ...
};

In Zukunft unterstützt?

/**
 * A promise for the user's favorite color.
 *
 * @promise FavoriteColorPromise
 * @fulfill {string} The user's favorite color.
 * @reject {TypeError} The user's favorite color is an invalid type.
 * @reject {MissingColorError} The user has not specified a favorite color.
 */

/**
 * Retrieve the user's favorite color.
 *
 * @returns {FavoriteColorPromise} A promise for the user's favorite color.
 */
User.prototype.getFavoriteColor = function() {
    // ...
};

Siehe Github-Diskussion unter: https://github.com/jsdoc3/jsdoc/issues/1197


1
Habe gerade das Gleiche gefunden. Link zu dem oben genannten Kommentar des Projektbesitzers github.com/jsdoc3/jsdoc/issues/1197#issuecomment-312948746
Mike Grace

4

Es gibt auch eine andere Art und Weise , dies zu tun , auch wenn es vielleicht werden DEPRECATED . Hervorheben der Macht, da jemand sagt , dass sie veraltet ist (überprüfen Sie die Kommentare zu dieser Antwort), während andere sagen, dass beide in Ordnung sind. Der Vollständigkeit halber melde ich es trotzdem.

Nehmen wir Promise.all()zum Beispiel, welches ein mit einem Array erfülltes Versprechen zurückgibt. Mit dem Punktnotationsstil würde es wie folgt aussehen:

{Promise.<Array.<*>>}

Es funktioniert mit JetBrains-Produkten (z. B. PhpStorm, WebStorm) und wird auch in den jsforce-Dokumenten verwendet .

Zum Zeitpunkt des Schreibens, wenn ich versuche, einige Dokumente mit PHPStorm automatisch zu generieren , wird standardmäßig dieser Stil verwendet, obwohl ich einen schlechten Verweis darauf gefunden habe.

Wie auch immer, wenn Sie die folgende Funktion als Beispiel nehmen:

// NOTE: async functions always return a Promise
const test = async () => { 
    let array1 = [], array2 = [];

    return {array1, array2};
};

Wenn ich PhpStorm die Dokumente generieren lasse, erhalte ich Folgendes :

/**
 * @returns {Promise.<{array1: Array, array2: Array}>}
 */
const test = async () => {
    let array1 = [], array2 = [];

    return {array1, array2};
};

0

Folgendes mache ich gerne (was vielleicht etwas übertrieben ist):

/**
 * @external Promise
 * @see {@link http://api.jquery.com/Types/#Promise Promise}
 */

/**
 * This callback is called when the result is loaded.
 *
 * @callback SuccessCallback
 * @param {string} result - The result is loaded.
 */

/**
 * This callback is called when the result fails to load.
 *
 * @callback ErrorCallback
 * @param {Error} error - The error that occurred while loading the result.
 */

/**
 * Resolves with a {@link SuccessCallback}, fails with a {@link ErrorCallback}
 *
 * @typedef {external:Promise} LoadResultPromise
 */

/**
 * Loads the result
 *
 * @returns {LoadResultPromise} The promise that the result will load.
 */
function loadResult() {
    // do something
    return promise;
}

Definieren Sie im Grunde das Basisversprechen mit einem Link zu einer Dokumentation (in diesem Fall verlinke ich auf die jQuery-Dokumentation), definieren Sie Ihre Rückrufe, die aufgerufen werden, wenn das Versprechen entweder aufgelöst wird oder fehlschlägt, und definieren Sie dann Ihr spezifisches Versprechen, das auf das Dokument verweist Rückrufdokumentation.

Verwenden Sie schließlich Ihren spezifischen Versprechungstyp als Rückgabetyp.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.