Wie kann man Rückrufe mit jsdoc richtig dokumentieren?

73

Ich habe eine ganze Weile im Internet nach dem besten Weg gesucht, Rückrufe mit jsdoc richtig zu dokumentieren, aber leider habe ich noch keinen großartigen gefunden.

Hier ist meine Frage:

Ich schreibe eine Node.js-Bibliothek für Entwickler. Diese Bibliothek bietet mehrere Klassen, Funktionen und Methoden, mit denen Entwickler arbeiten werden.

Um meinen Code klar und verständlich zu machen und (hoffentlich) in Zukunft einige API-Dokumentationen automatisch zu generieren, habe ich begonnen, jsdoc in meinem Code zu verwenden, um selbst zu dokumentieren, was passiert.

Angenommen, ich definiere eine Funktion wie die folgende:

function addStuff(x, y, callback) {
  callback(x+y);
});

Mit jsdoc dokumentiere ich diese Funktion derzeit wie folgt:

/**
  * Add two numbers together, then pass the results to a callback function.
  *
  * @function addStuff
  * @param {int} x - An integer.
  * @param {int} y - An integer.
  * @param {function} callback - A callback to run whose signature is (sum), where
  *  sum is an integer.
  */
function addStuff(x, y, callback) {
  callback(x+y);
});

Ich bin der Meinung, dass die obige Lösung etwas hackig ist, da ich nicht in absoluten Zahlen angeben kann, was die Rückruffunktion akzeptieren soll.

Im Idealfall möchte ich etwas tun wie:

/**
  * Add two numbers together, then pass the results to a callback function.
  *
  * @function addStuff
  * @param {int} x - An integer.
  * @param {int} y - An integer.
  * @param {callback} callback - A callback to run.
  * @param {int} callback.sum - An integer.
  */
function addStuff(x, y, callback) {
  callback(x+y);
});

Das oben Gesagte scheint es mir zu ermöglichen, einfacher zu vermitteln, was mein Rückruf akzeptieren muss. Ist das sinnvoll?

Ich denke, meine Frage ist einfach: Wie kann ich meine Rückruffunktionen mit jsdoc am besten klar dokumentieren?

Vielen Dank für Ihre Zeit.

rdegges
quelle
1
Mögliches Duplikat von Wie dokumentiere ich Rückrufe mit JSDoc?
Victor Sergienko

Antworten:

96

JSDoc 3 verfügt genau zu diesem Zweck über ein @ callback-Tag . Hier ist ein Anwendungsbeispiel:

/**
 * Callback for adding two numbers.
 *
 * @callback addStuffCallback
 * @param {int} sum - An integer.
 */

/**
 * Add two numbers together, then pass the results to a callback function.
 *
 * @param {int} x - An integer.
 * @param {int} y - An integer.
 * @param {addStuffCallback} callback - A callback to run.
 */
function addStuff(x, y, callback) {
  callback(x+y);
}
Jeff Williams
quelle
18
Dies wird von Visual Studio IDE nicht unterstützt. Die andere Antwort hier @param {function(int):void} callbackfunktioniert in VS und ist auch viel prägnanter.
Dies ist, was ich in Visual Code gemacht habe.
Luis.espinal
1
Wenn dies ein Rückruf zum Hinzufügen von zwei Nummern wäre, sollte der Rückruf zwei Parameter haben. Ich glaube, wir möchten, dass callback(x,y)die Rückrufzeile sagt und ein weiteres @param in die Rückruf-Dokumentzeichenfolge einfügt.
Johnklawlor
@ Johnklawlor, das glaube ich nicht. Dies ist eine Vereinfachung seitens des OP. Wenn seine Bibliothek mit den beiden Nummern fertig ist, die möglicherweise früher, aber in diesem Fall aus seiner addStuffMethode, erhalten wurden, wird das Ergebnis an den Client zurückgegeben, indem die callbackvom Client bereitgestellte Funktion aufgerufen wird. Ziel dieser Frage ist es, dem Client, dem Benutzer der Bibliothek, klar zu machen, welche Parameter die Rückruffunktion haben sollte. Der Client hätte eine Funktion mit einem beliebigen Namen : function addStuffResult( res ) { /* do stuff with res */ }.
aamarks
40

Eine andere Möglichkeit besteht darin, den an den Rückruf übergebenen Wert folgendermaßen zu beschreiben:

/**
  * Add two numbers together, then pass the results to a callback          function.
  *
  * @function addStuff
  * @param {int} x - An integer.
  * @param {int} y - An integer.
  * @param {function(int)} callback - A callback to run whose signature is (sum), where
  *  sum is an integer.
  */
function addStuff(x, y, callback) {
    callback(x+y);
});

Verwenden Sie, um den Rückgabetyp des Rückrufs zu dokumentieren @param {function(int):string}.

Yaki Klein
quelle
1
Ich mochte diese Methode, da meine IDE (Netbeans) sie unterstützt, aber das @ callback-Tag nicht zu erkennen scheint
Justin Emery
1
Was ist mit dem Rückgabewert von function(int)?
Maslow
6
@Maslow function(int):string(als Beispiel) funktioniert für mich in Visual Studio Code.
Inkling
1
@param {function(error):void} callback - Returns null if no error occurred.Ich habe es gerade mit Werken herausgefunden, aber es steht "arg0: any". Das muss errorsein, Errordamit Visual Studio Code nach dem Testen aus irgendeinem Grund die korrekte Eingabe anzeigt. Was ich nicht verstehe, ist, dass ich viele Beiträge und Probleme gelesen habe, die besagen, dass Typen beim Schreiben von Typen nicht zwischen Groß- und Kleinschreibung unterscheiden. Kleinbuchstaben sollten jedoch nach dem Testen mit numberfür JavaScript mit primitiven Typen funktionieren . Ich dachte nur, ich merke das nur für den Fall, dass andere auf dasselbe Problem stoßen.
Nova
@Nova Errorist kein primitiver Typ?
yyny
8

Problemumgehung, damit VSCode es versteht

/**
 * @typedef {function(FpsInfo)} fpsCallback
 * @callback fpsCallback
 * @param {FpsInfo} fps Fps info object
 */

 /**
 * @typedef {Object} FpsInfo
 * @property {number} fps The calculated frames per second
 * @property {number} jitter The absolute difference since the last calculated fps
 * @property {number} elapsed Milliseconds ellapsed since the last computation
 * @property {number} frames Number of frames since the last computation
 * @property {number} trigger Next computation will happen at this amount of frames
 */

/**
 * FPS Meter - Returns a function that is used to compute the framerate without the overhead of updating the DOM every frame.
 * @param {fpsCallback} callback Callback fired every time the FPS is computed
 * @param {number} [refreshRate=1] Refresh rate which the fps is computed and the callback is fired (0 to compute every frame, not recommended)
 * @returns {function} Returns a function that should be called on every the loop tick
 * @author Victor B - www.vitim.us - github.com/victornpb/fpsMeter
 */
function createFpsMeter(callback, refreshRate = 1) {
    // ...
}

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Vitim.us
quelle
2

Möglicherweise komme ich zu spät zu dieser Antwort ... aber das ist mein Beitrag. Mit ES6 können wir dies tun:

    /**
 *
 * @param {import('../clients')} clients  
 */
export default function socketServer(clients) {
io.on('connection', (webClient) => {


    webClient.on('register', (data) => {
      clients.add(data, webClient);
    });
}

 server.listen(8081, function (err) {
    if (err) throw err;
    console.log('listening on port 8081');
  });

)

Im Ordner 'clients' haben wir eine index.js-Datei mit diesem Code

let clients = new Map();

/**
 * Add Client to Collection
 * @param {string} key
 * @param {object} client
 */
export function add(key, client) {
  clients.set(key, client);
}
/**
 * Remove Client from Collection
 * @param {string} key
 */
export function remove(key) {
  clients.delete(key);
}

export const size = () => clients.size;

Alle Funktionen, die in die Datei /clients/index.js exportiert werden, sind als JsDOC verfügbar und können über IntelliSense referenziert werden

Edgar Vicent
quelle