Можно ли не использовать отклонение в Обещании? - PullRequest
0 голосов
/ 15 октября 2018

Можно ли построить Обещание, которое никогда не отвергает?Я имею в виду, это своего рода анти-паттерн или это приемлемо?Позвольте мне проиллюстрировать это на примере.У меня есть класс ModifyURL, который состоит из многих методов, каждый метод делает что-то с массивом строк URI и возвращает Promise.Часть реализации выглядит следующим образом.

class ModifyURL {
    constructor() {

    }
    /**
     * Remove empty and invalid urls
     * @param {object} object containing arrays of links
     *
     * @return {object} object containing arrays of valid links
     */
    removeInvalid(data) {
        return new Promise((resolve,reject)=>{
            for (let key in data) {
                data[key] = data[key].filter( function(item) {
                    return !(item == '#' || !item || item == ' ');
                });
            }
            resolve(data)
        });
    }

    /**
     * Remove duplicates
     * @param {object} object containing arrays of links
     *
     * @return {object} object containing arrays of unique links
     */
    removeDuplicates(data) {
        return new Promise((resolve,reject)=>{
            for (let key in data) {
                data[key] = data[key].filter(function (item, pos) {
                    return data[key].indexOf(item) == pos;
                })
            }
            resolve(data)
        });
    }
    /**
     * Add full hostname to relative urls.
     * @param {object}  object containing arrays of links
     * @param {string} hostname to be added if link is relative
     *
     * @return  {object} object containing arrays of absolute links
     */
    fixRelativeLinks(data,hostname) {
        if(typeof data === 'object'){
            return new Promise((resolve,reject)=>{
                for (let key in data) {
                    data[key].forEach((v, i) => {
                        if(data[key][i]){
                            data[key][i] = URL.resolve(hostname, data[key][i])
                        }
                    })
                }
                resolve(data)
            })
        }
    }
}

Позже я включаю эти Обещания в цепочку, и она отлично работает.

                            modifyURL.removeInvalid(data).then(res=>{
                                return res
                            })
                            .then(()=>{
                                return modifyURL.fixRelativeLinks(data, res.request.href)
                            })
                            .then(modifyURL.removeDuplicates).then(res=>{
                                onSuccess(res)
                            }).catch(err=>{console.log(err)})

Как вы заметили, я не использую reject , и это выглядит немного странно.Причина в том, что в конце мне нужно получить некоторые данные.Даже если некоторые Promise в цепочке не справляются со своей задачей, мне нужно, наконец, разрешить с моим массивом строк URI.Вот почему я не отклоняю , потому что это разрывает мою Обещание цепочку.Но без reject я теряю способность отслеживать ошибки заранее.Как правильно решить эту задачу?

1 Ответ

0 голосов
/ 16 октября 2018

Можно ли построить Обещание, которое никогда не отвергается?

Да, все в порядке.Если в операции нет возможных ошибок, тогда вполне нормально, если обещание только разрешается.

Я имею в виду, является ли это своего рода анти-паттерном или приемлемым?

Вполне приемлемо иметь обещание, которое никогда не отклоняется (при условии, что существует некоторый путь кода, который он разрешит).Например, вы могли бы написать функцию, которая разрешает обещание после определенной задержки, например:

function delay(t, v) {
    return new Promise(resolve => {
        setTimeout(resolve, t, v);
    });
}

У меня есть класс ModifyURL, который состоит из многих методов, каждый метод делает что-то с массивомURI-строки и возвращает обещание.Часть реализации выглядит следующим образом.

Это все синхронные функции.Они не должны быть завернуты в обещания и не должны быть завернуты в обещания.Обещания для отслеживания асинхронных операций.Они создают более сложный код, чем это необходимо при использовании их с чисто синхронным кодом.

Хотя можно выполнять синхронные операции с обещаниями (как у вас), я бы назвал это антишаблоном, поскольку он делает код намного более сложным, чем просто использование обычных шаблонов синхронного кодирования, когда вы просто вызываете несколько функцийодин за другим, или если все они работают с одними и теми же данными, сделайте эти функции всеми методами объекта и вызывайте их один за другим.

Как вы заметили, я не использую отклонение, и он чувствуетнемного странноПричина в том, что в конце мне нужно получить некоторые данные.

Во-первых, вы неправильно используете здесь обещания с синхронным кодом.Но, как правило, с помощью асинхронного кода, ваш код решает, что произойдет в случае ошибки.Вы можете позволить отклонению распространяться и останавливать цепочку, или вы можете отловить отклонение локально и изменить его на то, что вы хотите, чтобы цепочка продолжалась, и цепочка не будет знать, что произошла какая-либо ошибка.Это зависит от вас и вашего кода.Вы полностью контролируете это.

Даже если какой-то Promise в цепочке не справляется со своей задачей, мне нужно окончательно решить с моим массивом строк URI.

Этоэто только правильная локальная обработка ошибок, поэтому вы ловите и обрабатываете любую ошибку локально, чтобы вы могли продолжить обработку остальных ваших данных и вернуть данные, которые были успешно обработаны.По своей концепции это ничем не отличается от использования try/catch с синхронным кодом для локального перехвата ошибок, чтобы вы могли их отлавливать, обрабатывать, как это уместно, и продолжать работу до конца.

Этопочему я не отказываюсь, потому что это разрывает мою цепочку обещаний.Но без отклонения я теряю способность правильно отслеживать ошибки.Как правильно справиться с такой задачей?

На этот вопрос нет общего ответа, поскольку он зависит от конкретного приложения, от того, что он делает, и от того, как вы хотите связаться с ним.и результаты, и ошибки.Иногда вы прерываете цепочку при первой ошибке (быстро проваливаются).Иногда вы пропускаете ошибки и просто возвращаете успешные результаты.Иногда вы возвращаете массив результатов и массив ошибок.Иногда вы возвращаете один массив, который имеет как результаты, так и ошибки, и вы предоставляете некоторые средства в формате данных, чтобы узнать, какая ошибка является, а какая - успешным.И вы можете изобрести столько других способов, сколько хотите сообщить о результатах и ​​ошибках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...