Làm thế nào để chỉ định độ phân giải và loại từ chối của lời hứa trong JSDoc?


83

Tôi có một số mã trả về một đối tượng hứa, ví dụ: sử dụng thư viện Q cho NodeJS.

var Q = require('q');

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

Làm thế nào để ghi lại giá trị trả về như vậy bằng JSDoc?


Tôi đã tự hỏi về một cái gì đó tương tự. Làm cách nào để ghi lại kiểu trả về của một hàm có thể trả về nhiều thứ khác nhau dựa trên đầu vào và trạng thái của ứng dụng?
Hoffmann

Sử dụng cú pháp ký tự đại diện : @returns {*}
Paul Sweatte 26/12/12

Cú pháp ký tự đại diện không cụ thể và không hữu ích.
Arikon 27/12/12

2
@arikon Có @returns {ErrorObject|ResultObject}giúp gì không? Sử dụng ký hiệu "ống" trong mô tả loại là một thực tế phổ biến.
John Doe

3
@ john-doe Không, không. Bởi vì hàm trả về đối tượng Promise, không chỉ đơn giản là kết quả hoặc lỗi.
Arikon,

Câu trả lời:


72

Ngay cả khi chúng không tồn tại trong Javascript, tôi thấy rằng JSdoc hiểu "các loại chung".

Vì vậy, bạn có thể xác định các loại tùy chỉnh của mình và sau đó sử dụng /* @return Promise<MyType> */. Kết quả sau tạo ra một TokenConsume (mã thông báo) → {Promise. <Token>} đẹp với liên kết đến Tokenloại tùy chỉnh của bạn trong tài liệu.

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

Nó thậm chí hoạt động với /* @return Promise<MyType|Error> */hoặc /* @return Promise<MyType, Error> */.


1
@Sebastian vâng đây là ý tưởng!
jillro

Đối với YUIDoc, tôi tìm thấy tác phẩm này:@return {Promise|Token}
J Chris A

ý kiến ​​hay! tôi đã sửa đổi nó thành:@returns {Promise<ForumPost>|Promise<false>|Error}
Przemek Lewandowski

1
Tôi thực sự không thích giải pháp này vì jsdoc tách typedef thành một trang khác với hàm trả về nó. Nó cũng yêu cầu bạn đặt tên cho tất cả các loại đối tượng có thể phân giải của mình, nhưng tất cả những gì bạn thực sự muốn làm là trả về nhiều giá trị và bọc chúng trong một đối tượng.
Bob McElrath

2
Cập nhật từ chủ dự án về các giải pháp hiện tại và những gì đang có kế hoạch phát hành github.com/jsdoc3/jsdoc/issues/1197#issuecomment-312948746
Mike Grace

7

Tôi có xu hướng xác định một kiểu bên ngoài cho lời hứa:

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

Bây giờ bạn có thể mô tả trong @returntuyên bố của tài liệu chức năng của bạn điều gì sẽ xảy ra với lời hứa:

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

6

Với JSDoc, bạn cũng có thể tạo các kiểu tùy chỉnh bằng cách sử dụng @typedef. Tôi sử dụng điều này khá nhiều nên các đạo cụ / tham số là chuỗi hoặc mảng liên kết đến mô tả của loại (giống như stringtôi đã tạo typedef bao gồm các bản địa có sẵn cho chuỗi (xem ví dụ JSDoc bên dưới). Bạn có thể xác định một loại tùy chỉnh theo cách tương tự. Điều này là do bạn không thể sử dụng ký hiệu dấu chấm đối tượng cho các kết quả trả về như bạn có thể đối với @property để biểu thị những gì có trong kết quả trả lại. Vì vậy, trong trường hợp bạn đang trả về một thứ gì đó giống như một đối tượng, bạn có thể tạo một định nghĩa cho kiểu đó (' @typedef MyObject) và sau đó @returns {myObject} Definition of myObject.

Tuy nhiên, tôi sẽ không phát điên với điều này, bởi vì các loại phải càng theo nghĩa đen càng tốt và bạn không muốn làm ô nhiễm các loại của mình, nhưng có những trường hợp bạn muốn xác định loại một cách rõ ràng và vì vậy bạn có thể ghi lại trong đó (một ví dụ điển hình là Modernizr ... nó trả về một đối tượng, nhưng bạn không có tài liệu về nó, vì vậy hãy tạo một typedef tùy chỉnh nêu chi tiết những gì có trong trả về đó).

Nếu bạn không cần phải đi theo tuyến đường đó, thì như ai đó đã đề cập, bạn có thể chỉ định nhiều loại cho bất kỳ @param, @property hoặc @return nào bằng cách sử dụng đường dẫn |.

Trong trường hợp của bạn, bạn cũng nên ghi lại một @throwsbởi vì bạn đang ném một 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
*/

1
Đáng buồn thay, điều này không hoạt động trong PHPStorm làm nổi bật loại trong @typedefthẻ là chưa được giải quyết. Yeah, duh, tôi đang xác định nó ngay tại đây!
David Harkness

Tôi không ném Lỗi, chỉ tạo ra cá thể của nó để vượt qua nó để Q.reject ()
Arikon

6

Cú pháp hiện được hỗ trợ bởi 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() {
     // ...
};

Được hỗ trợ trong tương lai?

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

Xem thảo luận trên github tại: https://github.com/jsdoc3/jsdoc/issues/1197


1
Chỉ cần tìm thấy điều tương tự. Liên kết đến nhận xét được tham chiếu ở trên từ chủ dự án github.com/jsdoc3/jsdoc/issues/1197#issuecomment-312948746
Mike Grace

4

Ngoài ra còn có một cách khác để làm điều này mặc dù nó thể KHÔNG ĐƯỢC SỬ DỤNG . Nhấn mạnh vào might do ai đó nói rằng nó không được dùng nữa (kiểm tra các nhận xét cho câu trả lời đó) trong khi những người khác nói một trong hai câu trả lời là tốt. Tôi đang báo cáo nó vì lợi ích của sự đầy đủ.

Bây giờ, lấy Promise.all() ví dụ trả về một Lời hứa được thực hiện với một mảng. Với kiểu ký hiệu dấu chấm, nó sẽ giống như hình dưới đây:

{Promise.<Array.<*>>}

Nó hoạt động trên các sản phẩm JetBrains (ví dụ: PhpStorm, WebStorm) và nó cũng được sử dụng trong tài liệu jsforce .

Tại thời điểm viết bài khi tôi cố gắng tạo tự động một số tài liệu bằng PHPStorm, nó được đặt mặc định theo kiểu này mặc dù tôi thấy tham chiếu kém về nó.

Dù sao nếu bạn lấy hàm sau đây làm ví dụ:

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

    return {array1, array2};
};

Khi tôi để PhpStorm tạo tài liệu, tôi nhận được điều này:

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

    return {array1, array2};
};

0

Đây là những gì tôi muốn làm (có thể hơi quá tay):

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

Về cơ bản, hãy xác định lời hứa cơ sở với một liên kết đến một số tài liệu (trong trường hợp này tôi đang liên kết với tài liệu jQuery), xác định các lệnh gọi lại của bạn sẽ được gọi khi lời hứa đó giải quyết hoặc thất bại, sau đó xác định lời hứa cụ thể của bạn liên kết trở lại tài liệu gọi lại.

Cuối cùng, sử dụng loại lời hứa cụ thể của bạn làm loại trả lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.