Ответы пользователя по тегу JavaScript
  • Как получить элемент объекта в nodejs?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Тут не важно, нода или не нода.
    Есть два варианта:
    1. Перебором.
    2. Построить обратный индекс, где ключи и значения поменять местами.
    Может быть случай, когда несколько ключей имеют одинаковые значения, поэтому нужно держать для каждого элемента индекса массив ключей.
    var data = {
    	key1: "value1",
    	key2: "value2",
    	key3: "value1",
    	key4: "value2",
    	key5: "value3"
    };
    var index = {};
    for (var key in data) {
    	var value = data[key];
    	if (index[value]) index[value].push(key);
    	else index[value] = [key];
    }
    console.dir(index);

    Вывод:
    { value1: [ 'key1', 'key3' ],
      value2: [ 'key2', 'key4' ],
      value3: [ 'key5' ] }

    Конечно, индекс нужно перестраивать при изменении исходного объекта.
    Ответ написан
  • [Асинхроность и nodejs] Кто что использует против callback hell и почему?

    MarcusAurelius
    @MarcusAurelius
    автор Impress Application Server для Node.js

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

    
    var dataRequests = [];
    // массив запросов к разным данным (БД, файлы, сетевые вызовы)
    var dataResults  = {};
    // я предпочитаю не использовать массив results, который дает async
    // а вместо этого делать именованные фрагменты данных
    // и писать их в свой хеш
    
    // добавляем один запрос к данным
    dataRequests.push(function(callback) {
    	db.queryRow(
    		'SELECT * FROM TableName1 where Field1=?', [someValue1],
    		function(err, res) {
    			dataResults.firstPiceName = res;
    			callback(err, null);
    		}
    	);
    });
    
    // добавляем второй запрос к данным
    dataRequests.push(function(callback) {
    	db.queryValue(
    		'SELECT count(*) FROM TableName2 where Field2=?',
    		[someValue2],
    		function(err, res) {
    			dataResults.secondPiceName = res;
    			callback(err, null);
    		}
    	);
    });
    
    // вызываем массив запросов асинхронно
    async.series(dataRequests, function(err, results) {
    	// тут делаем бизнес-логику над dataResults в котором у нас есть
    	// все фрагменты данных .firstPiceName и .secondPiceName
    	// и формируем общий результат
    });
    

    А еще рекомендую ставить тег "node.js" на вопросы по ноде.

    Ответ написан
    1 комментарий
  • Подсоветуйте фреймворк для node?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Как основной автор Impress, не буду я его советовать, но вот несколько слов скажу, чтобы не было лишних ожиданий от фреймворка. И дам советы, которые на любом фреймворке помогут Вам написать хороший проект.

    Ответы:

    agentx001:
    Сильно много мне не нужно, MVC да рендринг страниц на сервере.

    Что такое MVC нет общего мнения, так случается, что каждый поймет это по-разному, потом напишет что-попало, и назовет это MVC. Так вот, Impress это не MVC, если понимать MVC, как отдельное написание контроллеров, моделей и представлений. Не будем обсуждать, что такое MVC, это очень затертый термин, и мы запутаемся в домыслах, которые вокруг него нагромождены. Лучше я скажу, что ждать от фреймворка: Impress, сам по себе, это универсальный контроллер, он как раз написан для того, чтобы не писать контроллеров. В нем есть реализация представления — это рендереры, один из рендереров — это шаблонизатор (с его помощью можно рендерить не только HTML, но и CSV, CSS, TXT и что угодно), но есть еще рендерер для JSON, он совсем простой, можно дописывать другие рендереры, для других форматов данных, если шаблонизация не подходит, например, для бинарных данных. Еще в Impress есть реализация логики приложений — которая разделяется на три части: (а) логику модели данных предметной области, (б) логику представления, т.е. логику рендеринга, (в) логику библиотек общего назначения, не связанных с предметной областью. Логика предметной области — это бизнес-логика приложения, например: алгоритм вычисления маршрута доставки груза, для системы крекинга грузов. Логика рендеринга — это если нужно сформировать данные для рендеринга при помощи императивного кода (т.е. при помощи обычного алгоритмического программирования с условиями, циклами и вызывами), а не только при помощи декларативных шаблонов и декларативных условий в них. Логика библиотек общего назначения — это все универсальные задачи, которые могут быть переиспользованы в других проектах, например, генерация DOCX документа, валидация данных, чтение количества кадров из анимированного GIFа и т.д. Все эти три вида логики (кода), гораздо важнее отделать друг от друга, чем модель от представления. А вот отделать представление от логики представления — это вообще страшная ересь, в которую впадают многие MVC-фреймворки.

    agentx001:
    Понравился этот новенький impress, но не стремлюсь использовать самопальный продукт, могущий в любой момент свернуться и даже не имеющий документации…

    Кроме самописных Вы еще какие знаете? Может есть какие-то автоматически писанные или сгенерированные? Есть статьи, есть примеры, часть API уже документирована, например, вот тут: impress/wiki. Скоро будут скринкасты, я уже об этом говорил. И в Impress очень мало кода, ядро весит 43кб. Код написан аккуратно, его можно прочитать за 5 дней, если читать по 5 страниц на ночь. Примеры готового веб-приложения (админ-панель для БД MySQL и MongoDB) даются вместе с системой и описываются тут: http://habrahabr.ru/post/192302/

    rozhik:
    По поводу критики impress — я бы таки выбрал другой. Очень странная архитектура, если он выживет — то явно поменяет не только половину апи — но и принципы расположения файлов.

    Фреймворк не на пустом месте появился, файловые структуры, как и API, созданы как портированные на ноду, наработки моей команды за последние 15 лет на Delphi, C#, PHP и JavaScript. Структура каталогов и API будут наращиваться, но не переделываться кардинально, я уже нашел для себя золотую середину в архитектуре систем. Вот что будет меняться в ближайшие месяцы — это формат конфига, т.е. Impress же не просто фреймворк, это сервер приложений, и он может сразу обслуживать несколько приложений (на разных доменах). Для этого, конфиг будет разделен на основные настройки и отдельную конфигурацию, для каждого приложения. Но конфиг не вилик, его разнести на несколько файлов — не проблема, при чем, структура конфига не сильно изменится.

    Советы:

    1. Если у Вас сайт, то рендерите шаблоны на сервере, но если у Вас приложение, то сделайте одну страницу (ну или несколько основных страниц), и на сервере сделайте API на AJAX и JSON. Присылайте данные в клиентское приложение, будь то веб-приложение или мобильное приложение для iOS или Android или оконное приложение, на любом языке. Это гораздо универсальные и удобнее для интеграции и поддержки.

    2. Используйте оперативную память, не лазьте в базу данных постоянно. Нода — это великолепная возможность писать быстрые приложения, и даже не из-за того, что она не блокирующая, за последний год я понял, что правильное использование памяти гораздо более ускоряет, Вам даже не нужно делать операции ввода-вывода в реальном времени, все они могут быть отложенные (ленивые, лэйзи). Вместо этого, разворачивайте данные в память приложения, стройте хеши, объекты, массивы. Не нужно бояться, что нода запущена в несколько процессов, и запросы одного пользователя могут приходить в разные процессы и находить там разные структуры данных. Это можно решить, делая «прилипание» клиентов по IP адресу или по Cookie при помощи балансировщика, к отдельному процессу ноды. В Impress такой балансировщик есть встроенный, можно использовать nginx или сервисы Вашего дата-центра, для больших проектов можно и нужно привлекать аппаратные балансировщики. Между разными процессами так же можно взаимодействовать через ZeroMQ, TCP, HTTP, IPC и еще что-угодно. Таким образом, данные разных процессов, в зависимости от того, что это за данные, могут или дублироваться в памяти (кешироваться, если это общие данные) или быть разделены на «прилепленные» сессии или синхронизироваться между собой через межпроцессовое взаимодействие.

    3. Не очаровывайтесь технологиями, берите их как можно меньше, и лучше копайте вглубь, чем по верхам. Для ноды сейчас очень большое разнообразие всего написано, и есть какая-то общая тенденция, поподключать в проект сто модулей, которые делают совершенно плевые вещи, а те тянут за собой еще какие-то зависимости и потом оно расползается и становится совершенно неконтролируемым. Подумайте 100 раз перез тем, как написать require, а если есть несколько альтернатив, то потратьте немного времени чтобы пощупать их код, протестировать производительности и удобство, это сэкономит потом много времени.
    Ответ написан
    3 комментария
  • Node.js в качестве server-side для enterprise приложения?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Попробуйте сервер приложений Impress — http://habrahabr.ru/post/194250/
    Для PHP-разработчиков он будет более понятным, чем другие фреймворки, потому, что делать новые API-обработчики (урлы для AJAX запросов) можно без перезапуска всей системы, просто созданием файла. Решено много вопросов, многопоточный запуск, перезапуск отдельных потоков при вылетании, логирование, обмен данными между потоками, отдача статики, кеширование в памяти как статики, так и кода и данных, которые этот код плодит, кукизы, хорошие драйвера к СУБД, и много другого, в общем, все необходимое для разработки серверов приложений.
    Ответ написан
    2 комментария
  • [nodejs] fibrous конфликт с демкой madhums(express)

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Интересная библиотечка, стоит исследовать. К сожалению, я не использую экспресс, и не могу ответить квалифицировано, но подобная проблема возникала у людей github.com/goodeggs/fibrous/issues/10 Очевидно, что экспресс (или его плагины доступа к данным) портят структуры данных, которые создает fibrous, когда привязывается к вызову методов. Методы вешаются в очередь fibrous и когда настает время их исполнять и вернуть управление в нужное место, то оказывается, что данных нет. По хорошему, конечно, fibrous не должен навешивать данные на объекты, которые сам не создает, а должен у себя делать внутренние структуры данных и индексы для вызываемых методов. Ну это нужно изучать и переписывать библиотеку.
    Ответ написан
    Комментировать
  • Flash или JavaScript

    MarcusAurelius
    @MarcusAurelius
    автор Impress Application Server для Node.js
    Хоть ябольшой приверженец HTML5, но в IE без Canvas или SVG на одном JavaScript, думаю Вы не сделаете то что нужно. jQuery тут вообще ни при чем, это всего лишь сахар, а каких-то кардинально новых возможностей из браузера он не выжимает. Хотя, что понимать под редактором, если же речь идет про подложку картинки с масштабированием и надписью сверху, то это на JS просто. Что значит печать удаленно? Опишите подробнее.
    Ответ написан
    6 комментариев
  • Язык, технология и инструментарий для разработки блога с поддержкой Ajax?

    MarcusAurelius
    @MarcusAurelius
    автор Impress Application Server для Node.js
    PHP:
    [<?

    $fi = 'path/push-flag-file';
    $fileMod = filemtime($fi);
    $startTime = time();
    do {
    usleep(500000); // 0.5sec
    clearstatcache();
    } while (($dileMod==filemtime($fi)) && (time()-$dtartTime<1800)); // or 30 min timeout

    readfile($fi);

    ?>]

    JavaScript:
    function ServerPush() {
    $.ajax({
    type: «GET»,
    url: "/path/push.php",
    async: true,
    dataType: «json»,
    cache: false,
    timeout: 1800000, // 30min 60000 = 1 min
    success: function(data) {
    // тут делайте с data что хотите
    if (PushTimeout) clearTimeout(PushTimeout);
    PushTimeout = setTimeout(ServerPush, 500);
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
    if (PushTimeout) clearTimeout(PushTimeout);
    PushTimeout = setTimeout(ServerPush, 1000); // 1sec
    },
    });
    }
    Ответ написан
    4 комментария