Если оборачивать объект полностью — то да. Но в таком случае слишком много избыточных операций. Представьте себе, мы хотим использовать Sync(fs).readFile — а для этого программе нужно обработать и обернуть все функции объекта fs.
Ну так об этом и идет речь в последнем примере. Только FutureSync(fs) это уже слишком :)
Была еще мысль вот такого подхода (чтобы не портить Function.prototype):
Тогда продемонстрируйте мне удобный, понятный и безкостыльный nodejs код (с корректной обработкой ошибок), который:
a. Последовательно прочтет 3 файла один за другим, склеит и выведет их исходный код
б. Параллельно прочтет 3 файла, склеит и выведет их исходный код (но в жестко заданной последовательности)
a. на node-sync:
var Sync = require('sync'), fs = require('fs');
Sync(function(){
try {
var file1 = fs.readFile.sync(null, 'file1');
var file2 = fs.readFile.sync(null, 'file2');
var file3 = fs.readFile.sync(null, 'file3');
console.log([file1, file2, file3].map(String).join(''));
}
catch (e) {
console.error(e);
}
})
б. на node-sync:
var Sync = require('sync'), fs = require('fs');
Sync(function(){
try {
var file1 = fs.readFile.future(null, 'file1');
var file2 = fs.readFile.future(null, 'file2');
var file3 = fs.readFile.future(null, 'file3');
console.log([file1.result, file2.result, file3.result].map(String).join(''));
}
catch (e) {
console.error(e);
}
})
> Костыль это не новые возможности, а переиначивание уже существующих возможностей для чьего-нибудь удобства. Да и то, удобства субъективного.
Согласен. Но это не относится к данному решению.
> Node.js специально сделан асинхронным, без блокирования потока, а тут наоборот возвращаются блокировщики и т.п.
Ну вы уже прям как MagaSoft. Вы хоть поняли, как это работает?
> То что делается с целью «асинхронное, но чтобы выглядило типа как синхронное» — костыли. Причем, очень вредные в целом, имхо.
Что такое «асинхронное» и как это должно выглядеть? Если есть устоявшееся мнение, что «асинхронное» в nodejs выглядит в виде анонимного коллбэка с ошибкой первым аргументом — это всего лишь последствие синтаксических свойств языка на текущий момент его развития. Если есть способ упростить эту конструкцию в свете развития возможностей технологии — это не костыль.
Вот костыль:
someAsyncFunction(function(err, result){
if (err) return callback(err); // <-- костыль
})
Нет костыля:
try {
// костыль? а call, apply, bind - тоже костыли?
var result = someAsyncFunction.sync();
}
catch (e) {
// нет костыля
}
> Люблю Javascript и не хочу чтобы отношение к нему стало такое же как к PHP сейчас.
Я тоже люблю Javascript. Но то, что вы будете называть костылями новые его возможности, явно ему не поможет )
> Сейчас есть шанс, что Node.JS превратится в подобие PHP, появятся толпы говноскриптеров, которые прочитали только как вывести alert и побежали сайты создавать.
ниасилят, имхо
var fs = require('fs');
var exec = require('child_process').exec;
var Sync = require('sync');
Sync(function(){
var who = exec.sync(null, 'whoami'); // seq
var groups = exec.future(null, 'groups ' + who); // par
var src = fs.readFile.future(null, __filename, 'ascii'); // par
console.log('Groups: ' + groups.result.trim());
console.log('This file has ' + src.result.length + ' bytes');
})
(результат идентичен, groups и src работают параллельно)
А в следующей версии планирую добавить автоматическое преобразование объектов:
var Sync = require('sync');
var fs = Sync(require('fs'));
var cp = Sync(require('child_process'));
Sync(function(){
var who = cp.exec('whoami'); // seq
var groups = cp.execFuture('groups ' + who); // par
var src = fs.readFileFuture(__filename, 'ascii'); // par
console.log('Groups: ' + groups.result.trim());
console.log('This file has ' + src.result.length + ' bytes');
})
> Для node.js это получается костыльно-ориентированное программирование
А как вы назовете тогда соглашение о том, что «callback всегда должен быть последним и ошибку принимать первым агрументом»?
Честно говоря, я рассчитывал на бóльшую компетентность читателей.
Вы перед тем, как писать такой комментарий, лучше бы изучили вопрос по подробнее. «Претендуешь — соответствуй».
Это yield — поддержка программных прерываний потока без глобальной блокировки процесса. Найдите мне 10 библиотек, использующих нативный yield.
Если collection.find.sync(collection, {'_id':new ObjectID(«aaaaaaaaaaaa»)) вернет err первым аргументом в callback, который передает ему sync(), то этот err вылетит в поток. Если он не будет словлен потоком, то err попадет в callback, который мы передаем в Sync(fn, callback).
Простой пример:
// Обычная асинхронная функция, вызывает callback через 1 сек с ошибкой
function someAsyncFunction(callback) {
setTimeout(function(){
callback('something went wrong');
}, 1000)
}
// Вариант 1
// Новый поток
Sync(function(){
try {
// вызываем функцию синхронно, птичка вылетит отсюда
someAsyncFunction.sync();
}
// ловим ошибку. в catch. правда.
catch (e) {
console.log(e); // something went wrong
}
})
// Вариант 2
Sync(function(){
// вызываем функцию синхронно
someAsyncFunction.sync();
// или вот так
throw new Error('something went wrong');
}, function(err){
// Ловим здесь любой exception из текущего потока
console.log(e); // something went wrong
})
В примере со статьи, любая ошибка, вылетевшая из любой вызванной там функции, попадет в результирующий callback:
function syncFunction() {
//
// внутри очень красивый синхронный код
// отсюда можно throw
// любая ошибка из sync() = throw = попадет в результирующий callback
//
}.async()
syncFunction(function(err){
console.log(err); // вот сюда
})
> Пример не удачен, хотя в ноде и не мало мест где можно далеко уйти с колбеками.
Дайте пример лучше — обновлю статью.
Была еще мысль вот такого подхода (чтобы не портить Function.prototype):
Но это, как по мне, хуже, чем:
a. Последовательно прочтет 3 файла один за другим, склеит и выведет их исходный код
б. Параллельно прочтет 3 файла, склеит и выведет их исходный код (но в жестко заданной последовательности)
a. на node-sync:
б. на node-sync:
Согласен. Но это не относится к данному решению.
> Node.js специально сделан асинхронным, без блокирования потока, а тут наоборот возвращаются блокировщики и т.п.
Ну вы уже прям как MagaSoft. Вы хоть поняли, как это работает?
yield — это новые возможности, или костыль?
Что такое «асинхронное» и как это должно выглядеть? Если есть устоявшееся мнение, что «асинхронное» в nodejs выглядит в виде анонимного коллбэка с ошибкой первым аргументом — это всего лишь последствие синтаксических свойств языка на текущий момент его развития. Если есть способ упростить эту конструкцию в свете развития возможностей технологии — это не костыль.
Вот костыль:
Нет костыля:
> Люблю Javascript и не хочу чтобы отношение к нему стало такое же как к PHP сейчас.
Я тоже люблю Javascript. Но то, что вы будете называть костылями новые его возможности, явно ему не поможет )
> Сейчас есть шанс, что Node.JS превратится в подобие PHP, появятся толпы говноскриптеров, которые прочитали только как вывести alert и побежали сайты создавать.
ниасилят, имхо
Код должен отражать выполняемую задачу при минимальном количестве «шума».
Бонус — у node-sync меньше шума.
Тогда функциональное программирование в целом — это один большой костыль?
Библиотека Seq — костыль?
vs
(результат идентичен, groups и src работают параллельно)
А в следующей версии планирую добавить автоматическое преобразование объектов:
А как вы назовете тогда соглашение о том, что «callback всегда должен быть последним и ошибку принимать первым агрументом»?
так о чем мы вообще говорим?
> ничего некорректного в обычной обработке нет
а я говорил, что есть?
> Далее, к третьей проблеме, расширение базовых прототипов это реально плохая идея.
Согласен. Но это чертовски удобно.
Да, и вправду, это syntactic sugar, заисключанием парочки нюансов, о которых вы не знаете (всего-то).
Вы перед тем, как писать такой комментарий, лучше бы изучили вопрос по подробнее. «Претендуешь — соответствуй».
Это yield — поддержка программных прерываний потока без глобальной блокировки процесса. Найдите мне 10 библиотек, использующих нативный yield.
Если collection.find.sync(collection, {'_id':new ObjectID(«aaaaaaaaaaaa»)) вернет err первым аргументом в callback, который передает ему sync(), то этот err вылетит в поток. Если он не будет словлен потоком, то err попадет в callback, который мы передаем в Sync(fn, callback).
Простой пример:
В примере со статьи, любая ошибка, вылетевшая из любой вызванной там функции, попадет в результирующий callback:
> Пример не удачен, хотя в ноде и не мало мест где можно далеко уйти с колбеками.
Дайте пример лучше — обновлю статью.
Было бы интересно сравнить производительность данного подхода.
все же
не на столько удобно, как:
но в любом случае, удобнее чем:
слегка упростил пример