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

我已经花了相当长的时间在网上寻找用 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 清楚地记录我的回调函数的最好方法是什么?

打扰了。

39358 次浏览

JSDoc 3 has a @callback tag for exactly this purpose. Here's a usage example:

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

Another possibility is to describe the value passed to the callback this way:

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

To document the return type of the callback, use @param {function(int):string}.

Workaround to make VSCode understand it

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

enter image description here enter image description here

Possibly I'm arriving late to this answer...however this is my contribution. Using ES6 we can do this:

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


)

In the folder 'clients' we have an index.js file with this 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;

So, all functions that are being exported in file /clients/index.js are available as JsDOC and you can refer them via IntelliSense

@param {function(number):void} myCallback

Works well in VS Code and WebStorm as of 2021