Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 12.05.2014, 21:31
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Цитата:
Это даже не рекомендация, а обязательное правило, потому что catch может поймать только исключение в своем стеке.
В node есть модуль domain, который от части решает эту проблему. Также пляски с генераторами могут позволить юзать конструкцию try-catch, но ... это всё изврат, имхо
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 12.05.2014 в 21:35.
Ответить с цитированием
  #12 (permalink)  
Старый 13.05.2014, 01:10
Аватар для dmitry111
Профессор
Отправить личное сообщение для dmitry111 Посмотреть профиль Найти все сообщения от dmitry111
 
Регистрация: 26.03.2012
Сообщений: 823

Сообщение от kobezzza
2) Используй паттерны / фреймворки для работы с асинхронностью. Выбор фреймворка и паттерна зависит от предпочтений, я использую Async.
вот по поводу Async - как с ним работать?

Я понимаю для чего эти методы, но я не знаю где их применить
Например waterfall:

async.waterfall([
    function(callback){
        callback(null, 'one', 'two');
    },
    function(arg1, arg2, callback){
      // arg1 now equals 'one' and arg2 now equals 'two'
        callback(null, 'three');
    },
    function(arg1, callback){
        // arg1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
   // result now equals 'done'    
});


обходит несколько функций, результат которых идет к следующей и так до конца. Но на деле то, как с этим работать?


У меня много моментов в коде, когда метод одного модуля задействует метод другого модуля.

Вот пример моего кода:

var config = require('../config');

var maxPlayers = config.get('game:maxPlayers');

// проверяет наличие свободные мест
// true: отсутствие мест
exports.check = function (users, cb) {
   var result

  // тут какие-то расчеты

  process.nextTick(function () {
    cb(result);
  });
};



var waiting = require('../lib/waiting');

var allUsers = 10;

waiting.check(allUsers, function (waiting) {
  if (waiting) { 
  } else {
  }
});


Передалось, расчеты сделаны, со следующим тиком callback вернет результат.

Где мне тут использовать этот async?

Также если есть примеры кода (или проект) с использованием async, поделись! А то статей про async много, а в рабочем исполнении не находил. По статьям невозможно понять как это все вместе работает ))

Последний раз редактировалось dmitry111, 13.05.2014 в 01:40.
Ответить с цитированием
  #13 (permalink)  
Старый 13.05.2014, 01:19
Аватар для dmitry111
Профессор
Отправить личное сообщение для dmitry111 Посмотреть профиль Найти все сообщения от dmitry111
 
Регистрация: 26.03.2012
Сообщений: 823

Сообщение от melky
кстати, что ты имеешь в виду под "node.js" ? веб-сервер? так это ж только один компонент node.js

наверное ты имел в виду express\connect

имею в виду процесс взаимодействия модулей между собой. Не обязательно express\connect



Сообщение от melky
имхо, ответ дан на главной странице Node.js

я хочу сказать - ответ "везде, где есть ввод\вывод". но это я так думаю
вот я везде callback расставил, но это делает код менее понятным, ИМХО
Ответить с цитированием
  #14 (permalink)  
Старый 13.05.2014, 01:40
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Сообщение от dmitry111
var config = require('../config');

var maxPlayers = config.get('game:maxPlayers');

// проверяет наличие свободные мест
// true: отсутствие мест
exports.check = function (users, cb) {
   var result

  // тут какие-то расчеты

  process.nextTick(function () {
    cb(result);
  });
};
А зачем колбек просто так асинхронным делать? Вместе с расчетами логично асинхронно запускать.
Так или иначе, скоро в Nodejs будут доступны встроенные ES6 Promises, думаю, это повлияет на API большинства новых модулей, а может быть и самого Nodejs, я бы уже начал писать асинхронные скрипты в таком стиле:
// проверяет наличие свободные мест
exports.check = function (users) {
    return new Promise(function (resolve, reject) {
        setImmediate(function () {
            try {                
                var value;
                // тут какие-то расчеты
                resolve(value);
            } catch (reason) {
                reject(reason);
            }
        });
    });
};

var waiting = require('../lib/waiting');

var allUsers = 10;

waiting.check(allUsers).then(function (value) {
    if (value) {
        //есть свободные места
    } else {
        //нет свободных мест
    }
}, function (reason) {
    //произошла ошибка
});

Последний раз редактировалось Octane, 13.05.2014 в 02:15.
Ответить с цитированием
  #15 (permalink)  
Старый 13.05.2014, 02:12
Аватар для dmitry111
Профессор
Отправить личное сообщение для dmitry111 Посмотреть профиль Найти все сообщения от dmitry111
 
Регистрация: 26.03.2012
Сообщений: 823

Сообщение от Octane
А зачем колбек просто так асинхронным делать? Вместе с расчетами логично асинхронно запускать.
чтобы была пауза в работе.
До вызова callback происходят некоторые расчеты, далее пауза и вызов callback уже в порядке следующего тика.
Ответить с цитированием
  #16 (permalink)  
Старый 13.05.2014, 08:58
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от dmitry111
обходит несколько функций, результат которых идет к следующей и так до конца. Но на деле то, как с этим работать?
везде, где есть асинхронные шаги в логике на практике чаще всего требовался parallel

зацени этот говнокод. рылся по истории git'а, чтобы специально показать тебе пример:

Задача: добавить категорию (родительскую\дочернюю - зависит от параметра запроса)

async.waterfall([

                    // тут получаем родительскую категорию, если можно
                    function (done) {
                        if (fields.id == -1) {
                            done(null, null);
                        } else {
                            models.ProductCategoryModel.findById(fields.id, function (err, parentCategory) { done(err, parentCategory); });
                        }
                    },

                    // тут определяем дочернюю категорию 
                    function (parentCategory, done) {
                        var newCategory;
                        if (parentCategory) {
                            newCategory = new models.ProductSubCategoryModel();
                        } else {
                            newCategory = new models.ProductCategoryModel();
                        }
                        newCategory.title = fields.new_category_name;
                        if (parentCategory) {
                            done(null, parentCategory, newCategory);
                        } else {
                            newCategory.save(function (err, newCategory) { done(err, parentCategory, newCategory); });
                        }
                    },

                    // связываем родительскую и дочернюю категории
                    function (parentCategory, childCategory, done) {
                        if (parentCategory) {
                            parentCategory.children.push(childCategory);
                            parentCategory.save(done);
                        } else {
                            done(null, null);
                        }
                    }

                ], function (err, parentCateg) {
                    if (err) return next(err);
                    allIsCompleted(err);
                });


Сообщение от dmitry111
вот я везде callback расставил, но это делает код менее понятным, ИМХО
вот для ухода от callback-hell используют async\Q\другое
Ответить с цитированием
  #17 (permalink)  
Старый 13.05.2014, 09:30
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

У меня самые частые - это waterfall и parallel

Пример с waterfall:
// Получение данных пользователя
async.waterfall([
    // Получаем данные пользователя по сессии
    function (cb) {
    },

    // Получаем данные пользователя по запросу
    function (sessionUser, cb) {
    },

    // Делаем проверку доступа и если всё ок, 
    // то отдаём данные
    function (requestUser, sessionUser, cb) {
    },
], callback);


Для задач дробления через setImmediate или nextTick прекрасно подходят циклы async:

var count = 0;

async.whilst(
    function () { return count < 5; },
    
    function (callback) {
        count++;
        
        setImmediate(function () {
            ...
            callback();
        });
    },
    
    function (err) {
        ...
    }
);


Цитата:
Так или иначе, скоро в Nodejs будут доступны встроенные ES6 Promises, думаю, это повлияет на API большинства новых модулей, а может быть и самого Nodejs,
На саму ноду не повлияет никак. Дело в том, что в первых версиях ноды были именно промисы, но от них отказались, т.к. они были чрезвычайно не эффективны для задач ноды.

Дело в том, что при работа на сервере в ноде часто работа идёт с потоками, т.е. данные принимаются / отдаются чанками, что полностью противостоит модели промисов, когда данные получаются сразу. Делается это, как я уже говорил, из соображений эффективности.

Так что какой-то революции нативные промисы не сделают, но всё же хорошо, что их добавят
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 13.05.2014 в 09:36.
Ответить с цитированием
  #18 (permalink)  
Старый 13.05.2014, 09:41
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от kobezzza
Так что какой-то революции нативные промисы не сделают, но всё же хорошо, что их добавят
что такое "thunk" ?
раньше такого термина не встречал, а теперь он появился, вместе с появлением оператора yield

используется в этой либе: https://github.com/visionmedia/co

я так понял, с yield и thunk асинхронный код пишется, как синхронный. и он без callback'ов

UPD. вру thunk - частично исполняемая функция, которая принимает один аргумент - callback.
примерчики :
// read - это thunk
function read(callback) {
  fs.readFile('myfile.md', 'utf8', callback);
}
// readFile - генератор thunk'ов ?
function readFile(filename) {
  return function(callback) {
    fs.readFile(filename, 'utf8', callback);
  };
}

Последний раз редактировалось melky, 13.05.2014 в 09:46.
Ответить с цитированием
  #19 (permalink)  
Старый 13.05.2014, 09:50
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Цитата:
что такое "thunk" ?
Тоже хз Я думаю, что это реализация либы, а не какая то нативная конструкция.

Цитата:
я так понял, с yield и thunk асинхронный код пишется, как синхронный. и он без callback'ов
Угу, сахарок Но, как я уже говорил, что я пока не вижу киллер фич И меня смущает, что в реализации на генераторах юзается концепция: sleep-check-sleep-check... и т.д. не будет ли это дополнительной нагрузкой на приложения на сервере при повсеместном использовании? ... Хотя, возможно внутри Co используется другой подход, т.к. в примере вижу, что асинхронная функция предварительно врапится, т.е. теперь вместо колбеков мы получаем другую боль в заднице - следить за проксированием асинхронных функций

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

***

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

co(function *(){
  var a = yield get('http://google.com');
  var b = yield get('http://yahoo.com');
  var c = yield get('http://cloudup.com');
  console.log(a[0].statusCode);
  console.log(b[0].statusCode);
  console.log(c[0].statusCode);
})()


VS

async.map(['http://google.com', 'http://yahoo.com', 'http://cloudup.com'], get, (err, results) => {
    ...
});


Ну хз, мне второй вариант более по душе
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 13.05.2014 в 10:06.
Ответить с цитированием
  #20 (permalink)  
Старый 13.05.2014, 10:17
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от kobezzza
т.к. это просто наглядней, имхо
да, я сейчас хотел написать функцию факториала на co.. в общем, мне нужна подготовка)
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Управление скроллом "а-ля тач" HonesT Элементы интерфейса 2 27.08.2013 14:25
Решение проблемы кодировок для AJAX и PHP без iconv (cp1251 в AJAX) Serge Ageyev AJAX и COMET 10 24.04.2013 20:48
как можно зашифровать ссылку на сервере апече? olehpdatu Серверные языки и технологии 1 22.04.2013 11:51
Недопонимание философии Node.js Voronar AJAX и COMET 10 25.02.2013 14:00
Как сохранять данные на сервере по средствам <form>? goshikvia Общие вопросы Javascript 1 26.03.2009 14:06