web-dev-qa-db-fra.com

Comment spécifier le type de résolution et de rejet de la promesse dans JSDoc?

J'ai du code qui retourne un objet de promesse, par exemple utiliser Q library pour NodeJS.

var Q = require('q');

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

Comment documenter une telle valeur de retour en utilisant JSDoc?

57
Arikon

Même s'ils n'existent pas en Javascript, j'ai découvert que JSdoc comprend les "types génériques".

Vous pouvez donc définir vos types personnalisés, puis utiliser /* @return Promise<MyType> */. Le résultat suivant dans Nice TokenConsume (jeton) → {Promise. <Token>} avec un lien vers votre type Token personnalisé dans le document.

/**
 * @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
}

Cela fonctionne même avec /* @return Promise<MyType|Error> */ ou /* @return Promise<MyType, Error> */.

41
Guilro

J'ai tendance à définir un type externe pour la promesse:

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

Maintenant, vous pouvez décrire dans la déclaration @return de la documentation de votre fonction ce qu'il advient de la promesse:

/**
* @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');
}
7
miracula

Avec JSDoc, vous pouvez également créer des types personnalisés à l'aide de @typedef. J'utilise un peu cela alors les accessoires/paramètres qui sont des chaînes ou des tableaux sont liés à une description du type (comme pour string, j'ai créé un typedef qui inclut les natifs disponibles pour string (voir l'exemple JSDoc ci-dessous). Vous pouvez définir une Tapez de la même manière, car vous ne pouvez pas utiliser la notation point par objet pour les retours, comme @ property pour indiquer le contenu du retour. Ainsi, dans les cas où vous renvoyez quelque chose comme un objet, vous pouvez créer une définition pour ce type ('@typedef MyObject) puis @returns {myObject} Definition of myObject.

Cela ne me rend pas fou, cependant, car les types doivent être aussi littéraux que possible et vous ne voulez pas les polluer, mais il existe des cas où vous souhaitez définir le type explicitement, afin de pouvoir documenter ce qui est. dedans (un bon exemple est Modernizr ... il retourne un objet, mais vous n’avez aucune documentation à ce sujet, créez donc un typedef personnalisé qui détaille le contenu de ce retour).

Si vous n'avez pas besoin de suivre cette voie, vous pouvez spécifier plusieurs types pour chaque paramètre @param, @property ou @return, comme mentionné précédemment, à l'aide du tube |.

Dans votre cas, vous devez également documenter un @throws car vous lancez un 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
*/
6
shadowstorm

Syntaxe actuellement prise en charge par Jsdoc3:

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

Soutenu dans le futur?

/**
 * 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() {
    // ...
};

Voir la discussion sur github à l'adresse: https://github.com/jsdoc3/jsdoc/issues/1197

2
holmberd

Il existe également un autre moyen de procéder, même si peut être être OBSOL&EGRAVE;TE. L'accent est mis sur peut-être puisque quelqu'un dit qu'il est obsolète (vérifiez les commentaires de cette réponse) alors que (autres) dit que l'un ou l'autre va bien. Je le signale quand même par souci d'exhaustivité.

Maintenant, prenons Promise.all() par exemple, qui retourne une promesse remplie avec un tableau. Avec le style de notation par points, cela ressemblerait à ceci:

{Promise.<Array.<*>>}

Il fonctionne sur les produits JetBrains (par exemple, PhpStorm, WebStorm) et est également utilisé dans les jsforce docs .

Au moment où j'écris, lorsque j'essaie de générer automatiquement des documents avec PHPStorm, ce style est défini par défaut sur ce style, même si j'ai trouvé une mauvaise référence.

Quoi qu'il en soit si vous prenez la fonction suivante à titre d'exemple:

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

    return {array1, array2};
};

Quand je laisse PhpStorm générer la documentation, je reçois ceci:

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

    return {array1, array2};
};
2
Francesco Casula

Voici ce que j'aime faire (ce qui peut être un peu exagéré):

/**
 * @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;
}

Fondamentalement, définissez la promesse de base avec un lien vers une documentation (dans ce cas, je fais un lien vers la requête jQuery), définissez vos callbacks qui seront appelés lorsque la promesse soit résolue ou échoue, puis définissez votre promesse spécifique qui renvoie à la documentation de rappel.

Enfin, utilisez votre type de promesse spécifique comme type de retour.

0
niltz