用jsdoc记录回调的正确方法是什么?


76

我已经花了相当长的时间在互联网上寻找可使用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);
});

我觉得上面的解决方案有点像黑客,因为我无法绝对地指定回调函数应该接受什么。

理想情况下,我想执行以下操作:

/**
  * 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清楚地记录回调函数的最佳方法是什么?

感谢您的时间。


Answers:


99

JSDoc 3为此有一个@callback标记。这是一个用法示例:

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

18
Visual Studio IDE不支持此功能。这里的另一个答案@param {function(int):void} callback是在VS中工作,并且也更加简洁。

这就是我最终在Visual Code中所做的事情。
luis.espinal

1
如果这是一个将两个数字相加的回调,则该回调应具有两个参数。我相信我们希望回调行说出来callback(x,y)并在Callback文档字符串中添加另一个@param。
johnklawlor

@johnklawlor,我不这么认为。这是OP的简化。当他的库处理完可能在其他地方或更早获得的两个数字(但在这种情况下,是从他的addStuff方法中获得的结果)时,通过调用客户端callback提供的函数将结果返回给客户端。这个问题的目的是向客户端(库的用户)明确说明回调函数应具有的参数。客户端将具有任何名称的功能:function addStuffResult( res ) { /* do stuff with res */ }
aamarks

41

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

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


1
我喜欢这个方法,因为我的IDE(Netbeans)支持它,但似乎无法识别@callback标记
Justin Emery

1
包括的返回值function(int)呢?
马斯洛

6
@Maslow function(int):string(作为示例)在Visual Studio Code中对我有效。
暗示

1
刚刚发现使用了@param {function(error):void} callback - Returns null if no error occurred.作品,但上面写着“ arg0:任意”。的error一定是Error对Visual Studio代码来测试它后显示某种原因正确的打字。我不明白的是,我已经阅读了许多帖子和问题,说在编写类型时类型不区分大小写。尽管在使用numberJavaScript进行测试之后,小写字母仍应适用于原始类型。只是以为我只是注意到了这一点,以防其他人遇到同样的问题。
新星

@NovaError不是原始类型吗?
yyny

8

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

在此处输入图片说明 在此处输入图片说明


2

我可能迟到了这个答案...不过这是我的贡献。使用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进行引用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.