Полезно ли всегда возвращать обещание


Я использую bluebird для разработки некоторой оболочки api nodejs вокруг службы http. Многие функции в этой оболочке являются асинхронными, и поэтому имеет смысл возвращать обещания из этих реализаций.

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

Пример:

function parseArray(someArray){
    var result;
    // synchronous implementation
    return Promise.resolve(result);           
}

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

Считается ли это плохой практикой, есть ли причины, по которым мы не должны этого делать ?

2 5

2 ответа:

В синхронных методах нет смысла возвращать обещание.

Обещания обеспечивают абстракцию над параллелизмом. Когда параллелизм отсутствует, например, при предоставлении массива. Возвращение обещания ухудшает управление потоком и значительно замедляет его.

Это также передает неверное сообщение. На самом деле, обещать что-то без причины-это довольно распространенный анти-паттерн.

Один случай, когда он является полезным, когда метод может быть асинхронный - например: извлечение чего-то из кэша или запрос на это, если его там нет:

function getData(id){
     if(cache.has(id) return Promise.cast(cache.get(id));
     return AsyncService.fetch(id).tap(cache.put);
}

Если мы можем игнорировать perf, это плохо только в том случае, если используется пример реализации:

function parseArray(someArray) {
    var result;
    // synchronous implementation
    return Promise.resolve(result);           
}

Эта функция является беспорядком, потому что она может бросать синхронно, но также возвращает обещание. Функция, которая возвращает обещание, никогда не должна бросать-в противном случае вы потеряли большинство преимуществ обещаний, потому что теперь вы должны использовать как try-catch, так и .catch().

Правильный способ реализации - "аннотировать" функцию с помощью .method:

var parseArray = Promise.method(function() { 
    var result;
    //Promise.resolve(result) is unnecessary now
    return result;
});

Теперь функция гарантированно никогда не будет бросать синхронно и может использоваться последовательным образом.