12.05.2014, 21:31
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Цитата:
|
Это даже не рекомендация, а обязательное правило, потому что catch может поймать только исключение в своем стеке.
|
В node есть модуль domain, который от части решает эту проблему. Также пляски с генераторами могут позволить юзать конструкцию try-catch, но ... это всё изврат, имхо
Последний раз редактировалось kobezzza, 12.05.2014 в 21:35.
|
|
13.05.2014, 01:10
|
|
Профессор
|
|
Регистрация: 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.05.2014, 01:19
|
|
Профессор
|
|
Регистрация: 26.03.2012
Сообщений: 823
|
|
Сообщение от melky
|
кстати, что ты имеешь в виду под "node.js" ? веб-сервер? так это ж только один компонент node.js
наверное ты имел в виду express\connect
|
имею в виду процесс взаимодействия модулей между собой. Не обязательно express\connect
Сообщение от melky
|
имхо, ответ дан на главной странице Node.js
я хочу сказать - ответ "везде, где есть ввод\вывод". но это я так думаю
|
вот я везде callback расставил, но это делает код менее понятным, ИМХО
|
|
13.05.2014, 01:40
|
|
|
Регистрация: 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.
|
|
13.05.2014, 02:12
|
|
Профессор
|
|
Регистрация: 26.03.2012
Сообщений: 823
|
|
Сообщение от Octane
|
А зачем колбек просто так асинхронным делать? Вместе с расчетами логично асинхронно запускать.
|
чтобы была пауза в работе.
До вызова callback происходят некоторые расчеты, далее пауза и вызов callback уже в порядке следующего тика.
|
|
13.05.2014, 08:58
|
sinistral
|
|
Регистрация: 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\другое
|
|
13.05.2014, 09:30
|
|
Быдлокодер;)
|
|
Регистрация: 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, 13.05.2014 в 09:36.
|
|
13.05.2014, 09:41
|
sinistral
|
|
Регистрация: 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.
|
|
13.05.2014, 09:50
|
|
Быдлокодер;)
|
|
Регистрация: 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, 13.05.2014 в 10:06.
|
|
13.05.2014, 10:17
|
sinistral
|
|
Регистрация: 28.03.2011
Сообщений: 5,418
|
|
Сообщение от kobezzza
|
т.к. это просто наглядней, имхо
|
да, я сейчас хотел написать функцию факториала на co.. в общем, мне нужна подготовка)
|
|
|
|