Pull to refresh

Comments 31

Какой исходных код этих ф-ций get_profile и get_msgs?
parallel([
    get_profile(user),
    get_msgs(user)
]).

Согласно вашему прошлому топику он достаточно страшный…
возможно get_profile выглядела бы так:
function get_profile(user){

    var d = Deferred();
    
    if (!conn.connected()) {
        d.fail("Connection error " + conn.connectErrno + ": " + conn.connectError);
    }else{
        conn.query("SELECT * FROM users where user="+user, function (err, res){
            if (err) {
                d.fail(err);
            }else{
                d.call(res.fetchFirst())
            }
        })
    }
    
    return d;
}
Нееее, если уж делать врап, то он должен быть сам по себе, без диких конструкций внутри.
не совсем понимаю зачем делать обьект Deffered в таком виде, если можно снаружи легко проверить instanceof?
Если предварительно сделать врап для объекта conn, то получится
function get_profile(user){
    var d = Deferred();

    conn.query("SELECT * FROM users where user="+user)
        .error(function(e){d.fail(e)})
        .next(function(data){d.call(data)});

    return d;
}
коли уж conn.query() возвращает deferred, то должно быть так:
function get_profile(user){
     return conn.query("SELECT * FROM users where user="+user)
        .error(function(e){d.fail(e)})
        .next(function(data){d.call(data)});
}
Ошибся, вот так:
function get_profile(user){
     return conn.query("SELECT * FROM users where user="+user);
}

И обработчики уже вне этой функции навешивать
Ну вот. А теперь напишем функцию, которая будет делать врап за вас.

// simplified
function wrap (fn) {
   return function () {
      var d = Deferred(); 
      fn();
      return d;
   }
}


Вот это прибилизтельно то, что я делаю =)
Только вот в fn надо передать d, чтобы на нём вызвать колл/еррбэки
Ну блин, разумеется, но способы передачи разные есть, я и упростил. Ее можно и в параметры подмешать, и к самой функции прицепить (если параметры менять нельзя).
Мне лично кажется что в случае большой вложенности нужно ее уменьшать: это узкое место, не проще на сервере собрать один готовый объект и прислать его? Т.е. в первом случае вернуть объект user, в котором есть профиль, сообщения, последние комменты и тд. Зачем столько раз обращаться с запросами к серверу, если нет никакой зависимости между этими сущностями? Запрашиваем: верни user с комментами и профилем, сервер формирует одним json объектом ответ, нужен только профиль, пожалуйста.
а что, если это асинхронный запрос к бд?
Вы видимо про серверный js говорите, тогда посоветую использовать синхронный коннектор к базе) Либо библиотеку step https://github.com/creationix/step
синхронный на node.js? зачем?
во первых параллельная организация работы все равно решается с помощью воркеров, подключение к базе и отключение, имхо, должно быть синхронным. Время затраченное на подключение к локальной базе ничтожно, и вешать обработчик на это глупо — он лишь запутывает код. А вот запросы можно дергать как синхронно, так и асинхронно. Все зависит от времени и места.
подключение к базе осуществляется один раз при старте сервера (ну или несколько раз).
а запросы выполняются много раз и, я так понял, должны быть асинхронными
Все зависит от стиля программирования и решаемой проблемы. Я считаю что злоупотребление такими обертками подталкивает программиста к процедурному стилю. Как и излишняя вложенность калбеков, если такое присутствует, надо получше продумывать архитектуру приложения\класса. К вопросу о синхронности запросов: Если от какого-то запроса зависит дальнейшая работа приложения (например логин к системе), но асинхронность тут не нужна. Если это обновление какких-то данных, то однозначно асинхронность. Если это сохранение: тут спорно, кто-то блокирует работу пока оно не завершится, кто-то сохраняет на лету… каждый случай требует своего решения
странно. казалось бы, при чём тут такие обёртки к стилю программирования. что говнокод, что хороший код можно написать и с асинхронным подходом и с синхронным.
Слово «подталкивает» ключевое. Говнокод и процедурный стиль это разные вещи. А зачем забивать все одним микроскопом, если можно пользоваться двумя?=) Я считаю не нужно уходить в секту синхронности или асинхронности, всему свое место. Если у вас логин блокирует всю программу, то зачем точку входа запихивать в калбек, это не наглядно. Хотя личное дело каждого)
весь смысл асинхронного подхода в том, чтобы делать асинхронные запросы и что-то делать когда они обработаны, и что-то делать в промежутке между этими событиями (или дать другим делать что-то). Традиционные треды и дочерние процессы работают по-другому. Там и подход другой.
А что, если это на сервере выполняется? :-)
Ну что вы все время пару решений мусолите?
Подумали бы лучше как заврапить типичную проблему для формы:
есть поле, которое верифицируется аяксом и есть сабмит формы, которое требует верифицированного поля
обычно вешается на blur поля запрос, но некоторые браузеры подставляют значение в поле, так что неплохо бы верифицировать непустое поле на сабмите.
В результате на сабмите пара флагов на верификацию ( старт, успешно), а в запросах на последнюю флаг на сабмит формы ( что бы таки сделать сабмит если верификация прошла ).

Что происходит если таких полей в форме несколько представить можно, но страшно :)
UFO landed and left these words here
отправлено — надо ждать
не отправлено — надо отправить
получено — сабмитить форму

бастой тут и не пахнет
если обработчик упадёт с исключением — фейл будет вызван или мы так и не узнаем, что всё упало?
если исключение возникает внутри звена, например .next, то управление переходит в ближайший по порядку .error, где можно получить само сообщение исключения.
тогда зачем «Для генерации ошибки — вызывать метод fail() Deferred» если можно просто бросить исключение?
вообще, внутренние try{}catch{} это, по-моему, лишнее. По крайней мере, отлов должен быть опциональным.
Only those users with full accounts are able to leave comments. Log in, please.