Генератор Node.js Каламбур


Давний наблюдатель здесь. Я делаю генератор каламбур в JavaScript, и я искал какие-то отзывы/рекомендации. У меня нет большого опыта создания приложений с узла, и так много мой код выглядит немного как бессвязный. Этот класс предназначен для использования, как так:

let p = new Phrase("The dog likes cheese.")
p.generatePun().then((response) => {
    console.log(response)
})

В частности, я думаю, что веб-API вызов может быть структурирована лучше, но я не знаю, как. Я бы признательны за любую обратную связь!

Phrase.js

const util = require("./util.js");
const wordsApi = require("./rhymeApi.js");

const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

class Phrase {
    constructor(string, badwords = ["the", "on"]) {
        this.tokens = string.split(" ");
        this.badwords = badwords;
    }

    generatePun() {

        let nonBadWordsIndices = [];
        for (let i = 0; i < this.tokens.length; i++) {
            if (!this.badwords.includes(this.tokens[i].toLowerCase())) {
                nonBadWordsIndices.push(i)
            }
        }



        let replaceIndex = util.getRandomElement(nonBadWordsIndices);
        let wordToBePunned = this.tokens[replaceIndex];

        const isCapitalized = wordToBePunned[0] === wordToBePunned[0].toUpperCase();
        const isAllCaps = wordToBePunned === wordToBePunned.toUpperCase();
        const punctuation= wordToBePunned[wordToBePunned.length - 1];
        const isPunctuated = !letters.includes(punctuation);

        if (isPunctuated) {
            wordToBePunned = wordToBePunned.slice(0, wordToBePunned.length - 1)
        }

        return wordsApi.getRhyme(wordToBePunned).then((rhymes) => {
            let rhyme = util.getRandomElement(rhymes).word;
            if (isCapitalized) {
                rhyme = rhyme.replace(/\b\w/g, l => l.toUpperCase())
            }
            if (isAllCaps) {
                rhyme = rhyme.toUpperCase();
            }
            if (isPunctuated) {

                rhyme = rhyme + punctuation
            }



            let punnedPhrase = this.tokens.slice();
            punnedPhrase.splice(replaceIndex, 1, rhyme);
            return punnedPhrase.join(" ")

        }).catch((err) => {
            return "Error in generating pun: " + err;
        });

    }

    toString() {
        return this.tokens.join(" ");
    }
}

module.exports = Phrase;

util.js

let getRandomElement = (array) => {
    return array[Math.floor(Math.random()*array.length)];
}

//returns random int in [0, stop)
let getRandomIntInRange = (stop) => {
    return Math.floor(Math.random()*stop)
}


module.exports = {
    getRandomElement,
    getRandomIntInRange
}

rhymeApi.js

const rp = require('request-promise');

const options = {
    method: 'GET',
    uri: 'https://api.datamuse.com',
    json: true
}


let getRhyme = (word) => {
    let rhymeOptions = Object.assign({}, options);
    rhymeOptions.uri += '/words?rel_rhy=' + word;
    return rp(rhymeOptions)
}




module.exports = {
    getRhyme
}


149
3
задан 17 февраля 2018 в 07:02 Источник Поделиться
Комментарии
1 ответ

Это в основном, что доставит некоторое неудобство, действительно, нет ничего откровенно плохого с вашим кодом. Хорошая работа!


  • В util.js, getRandomElement можно использовать getRandomIntInRange - поскольку он нигде не используется, если getRandomElement не использовать его, он должен быть отброшен.

  • Избежать ненужного смешения let и const. Оба nonBadWordsIndices и replaceIndex не переназначены, но по какой-то причине let используется вместо const во время использования const другом месте. (Также в util.js и rhymeApi.js)

  • Что должно произойти, если пустая строка передается как ваша фраза? Я подозреваю, что нынешнее поведение не нужные.

  • Глотание ошибки-это плохо 99% времени. Библиотеки, что ошибки проглотить сделать запись ошибок в журнал, чтобы иметь возможность быстро обнаружить проблемы и устранить ее гораздо сложнее.

  • Он не обязателен для использования, но при создании URL-адресов, вы должны всегда использовать encodeURI или encodeURIComponent как требоваться, чтобы избежать таких проблем, как пытаются сделать рифмы для слов, содержащих &. Это особенно важно, если он будет использоваться в веб-приложении.

Следующие пункты являются более мои личные предпочтения, чем объективно неправильно.


  • Если поддерживается вашей среде, предпочитают деструктурируется в Object.assign. (Также, почему /words?rel_rhy= добавлены здесь, а не хранятся в параметрах объекта? Там может быть хорошая причина, но это что-то рассмотреть)

    let getRhyme = (word) => {
    return rp({
    ...options,
    uri: options.uri + '/words?rel_rhy=' + encodeURIComponent(word)
    })
    }

  • Асинхронные функции отличные! Используйте их вместо явного используя обещания, если это возможно.

  • isPunctuated будут более четко определены с /[a-z]$/i.test(wordToBePunned)аналогично, isCapitalized может быть определена как /^[A-Z]/.test(wordToBePunned) это также похоже на большую полезность методы для меня, Я бы скорее перенести их в файл утилит, если они используются в другом месте в вашем коде - и, возможно, даже если они не к тому, что если вы нуждаетесь в них больше нигде вы не до конца забыл, что вы уже сделали работу и переписать их.

  • Если isAllCaps правда, потом isCapitalized также должно быть верным, я бы предпочел проверить isCapitalized только если isAllCaps имеет значение false при изменении возвращенное слово.

  • Избегайте двойных отрицаний, это делает код не труднее читать. nonBadWordsIndices эквивалентно goodWordsIndices

2
ответ дан 19 февраля 2018 в 05:02 Источник Поделиться