【问题标题】:What's the proper way to document callbacks with jsdoc?用 jsdoc 记录回调的正确方法是什么?
【发布时间】:2014-08-04 13:58:34
【问题描述】:

我花了很长时间在互联网上寻找使用 jsdoc 正确记录回调的最佳方法,但不幸的是,我还没有找到一个很好的方法。

这是我的问题:

我正在为开发人员编写一个 Node.js 库。该库提供了开发人员将使用的多个类、函数和方法。

为了使我的代码清晰易懂,以及(希望)将来自动生成一些 API 文档,我已经开始在我的代码中使用 jsdoc 来自我记录正在发生的事情。

假设我定义了如下函数:

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

使用jsdoc,我目前正在记录这个函数如下:

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

我觉得上述解决方案有点 hack-ish,因为我无法绝对指定回调函数应该接受什么。

理想情况下,我想做这样的事情:

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

以上内容似乎可以让我更简单地传达我的回调需要接受的内容。这有意义吗?

我想我的问题很简单:用 jsdoc 清楚地记录我的回调函数的最佳方法是什么?

感谢您的宝贵时间。

【问题讨论】:

标签: javascript node.js jsdoc autodoc jsdoc3


【解决方案1】:

JSDoc 3 有一个 @callback tag 就是为了这个目的。这是一个用法示例:

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

【讨论】:

  • Visual Studio IDE 不支持此功能。这里的另一个答案,@param {function(int):void} callback 在 VS 中工作,也更简洁。
  • 这是我最终在 Visual Code 中所做的。
  • 如果这是一个添加两个数字的回调,回调应该有两个参数。我相信我们希望回调行说 callback(x,y) 并在回调文档字符串中添加另一个 @param。
  • @johnklawlor,我不这么认为。这是对 OP 的简化。当他的库完成处理可能更早在其他地方获得的两个数字时,但在本例中是通过他的addStuff 方法,通过调用客户端提供的callback 函数将结果返回给客户端。这个问题的目的是让客户端、库的用户清楚地知道回调函数应该有哪些参数。客户端将拥有一个任意名称的函数:function addStuffResult( res ) { /* do stuff with res */ }。
【解决方案2】:

另一种可能性是这样描述传递给回调的值:

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

要记录回调的返回类型,请使用@param {function(int):string}。

【讨论】:

  • 我喜欢这种方法,因为我的 IDE (Netbeans) 支持它,但似乎无法识别 @callback 标记
  • 包含function(int)的返回值怎么样?
  • @Maslow function(int):string(例如)在 Visual Studio Code 中为我工作。
  • 刚刚发现使用@param {function(error):void} callback - Returns null if no error occurred. 有效,但它显示“arg0: any”。 error 必须是 Error 以便 Visual Studio Code 在测试后显示正确的输入。我不明白的是我读过很多帖子和问题,说类型在编写类型时不区分大小写。在使用 number 测试 JavaScript 之后,小写应该适用于原始类型。只是想我只是注意到这一点,以防其他人遇到同样的问题。
  • @Nova Error 不是原始类型?
【解决方案3】:

让 VSCode 理解它的解决方法

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

【讨论】:

    【解决方案4】:

    可能我迟到了这个答案......但这是我的贡献。使用 ES6 我们可以做到这一点:

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

    在“clients”文件夹中,我们有一个包含此代码的 index.js 文件

    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;
    

    因此,在文件 /clients/index.js 中导出的所有函数都可以作为 JsDOC 使用,您可以通过 IntelliSense 引用它们

    【讨论】:

      【解决方案5】:
      @param {function(number):void} myCallback
      

      截至 2021 年,在 VS Code 和 WebStorm 中运行良好

      【讨论】:

      • 但是JSDoc没有官方支持,是吗?我在 jsdoc.app 上找不到任何此类示例。
      猜你喜欢
      • 2013-12-13
      • 1970-01-01
      • 2017-02-06
      • 2023-03-14
      • 2023-04-09
      • 2010-11-11
      • 2011-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多