안녕세계

[SK고용디딤돌] Node.js (4/10) - 6주차 본문

[SK고용디딤돌] Node.js (4/10) - 6주차

Junhong Kim 2016. 8. 9. 18:05
728x90
반응형

async


collection

ㄴ each : 두번째 매개변수가 병렬로 실행

ㄴ eachSeries : 두번째 매개변수가 시리즈로 실행

ㄴ map : 분류, 값에 태그를 붙여준다. n개의 원소를 가지고있으면 변형된 원소를 갖는다 (입출력개수가 같다)

ㄴ filter  iterator  function 에 논리식이 true가 되는 원소만 결과객체에 넣는다 ( <-> reject )

ㄴ reduce : 맵에 썻던걸 이용해서 요약을하는 것, 결과를 줄이는 것


series : 결과 값들을 배열로 만들어서 done callback에서 출력



< asynctest1.js >

var async = require('async');
var uuid = require('uuid');

// 1 ~ 10 사이의 정수를 생성해 배열에 저장
var arr = []; // 단순 연산함수에서는 사용해도 된다.
for(var i = 0; i < 5 ; i++) { // I/O 함수에서 for loop는 사용하지 않는다.
arr.push(Math.ceil(Math.random() * 10));
}
// 이 배열의 원소를 값으로 하고
// uuid 값을 키로하는 객체를 원소로하는 배열을 생성
async.map(arr, function(item, callback) { // iterate function (원소 하나하나에 적용될 function)
if(typeof(item) !== 'number') {
callback(new Error(item + ' is not a number!!!'))
} else {
//console.log(item);
var transformed = {};
transformed[uuid.v4()] = item;
callback(null, transformed);
}
}, function(err, results) { // 모두 끝냈을 때의 function
if(err) {
console.log(err);
} else {
console.log(results);
}
});





< asynctest2.js >

var async = require('async');
var uuid = require('uuid');

async.waterfall([
function(callback) {
var randInt = [];
for (var i = 0; i < 5; i++) {
randInt[i] = Math.ceil(Math.random() * 10);
}
callback(null, randInt) // 에러가 없으면 null
},
function(arg1, callback) {
async.map(arg1, function(item, done) {
var transformed = {};
transformed[uuid.v4()] = item;
done(null, transformed);
}, function(err, results) {
if (err) {
callback(err);
} else {
callback(null, results);
}
})
}
], function(err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}
});




< asynctest3.js >

var async = require('async');
var path = require('path');
var fs = require('fs');

var jsonPath = path.join(__dirname, 'sample.json');

var result = "";
var reader = fs.createReadStream(jsonPath);

reader.on('data', function(chunk) {
result += chunk.toString();
});

reader.on('end',function() {
var arr = JSON.parse(result);
async.filter(arr, function(item, callback1) {
callback1(null, item % 2 ===1);
}, function(err, results) {
if(err) {
console.log(err);
} else {
async.reduce(results, 0, function(memo, item, callback2) {
process.nextTick(function() {
callback2(null, memo + item);
});
}, function(err, results) {
if(err) {
console.log(err);
} else {
console.log(results);
}
});
}
});
});

※ nextTick() - 사리지는 순서가 중요할 때 사용한다, 마지막에 넣기 위해 쓰는 것임

※ async.filter는 조건이 맞으면 배열 원소를 저장 함




<파일을 로드해서 단어 읽기(1) - wordcount 선생님 코드>

// fs 모듈 가져오기
var fs = require('fs');
// path 모듈 가져오기
var path = require('path');
// async 모듈 가져오기
var async = require('async');

// 파일의 경로를 조인
var filePath = path.join(__dirname, '4300-0.txt');
// 입력 스트링
var inputStr = "";
// filepath 읽기 스트림을 만든다.
var reader = fs.createReadStream(filePath);
reader.on('data', function(chunk) {
inputStr += chunk.toString();
});
reader.on('end', function () {
var rexp = /[\u0000-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007FI—]+/g;
var strArr = inputStr.trim().replace(rexp, '^').split("^").sort();

console.time('...');

async.map(strArr, function(word, callback) {
//process.nextTick(function() { // 돌아가는것 끝나고 다시 하라고하는 것, push 많이하면 스택 꽉참, 병렬일 때는 안써도 됨,
var transformed = [];
transformed.push(word)
transformed.push(0);
callback(null, transformed);
//});
}, function(err, results) {
var strMap = new Map(results);
console.log(results);
console.log(strMap);
async.each(strArr, function(word, callback) {
//process.nextTick(function() {
strMap.set(word, strMap.get(word) + 1);
callback(null);
//});
}, function(err) {
var writer = fs.createWriteStream('wordcount_result.txt');
async.each(strMap, function(entry, callback) {
process.nextTick(function() {
writer.write(entry[0] + ": " + entry[1] + "\n");
callback();
});
}, function(err) {
console.timeEnd('...');
console.log('result saved!!!');
})
})
});
});

※ whilst는 정말 반복을 처리해야 할 때만 사용한다. (최후의 선택)





<파일을 로드해서 단어 읽기(2) - 장춘's 심폐소생>

var async = require('async');
var path = require('path');
var fs = require('fs');
var jsonPath = path.join(__dirname, '4300-0.txt');

var result = "";
var reader = fs.createReadStream(jsonPath);

reader.on('data', function(chunk) {
result += chunk.toString();
});

reader.on('end', function(){
// 기본적인 정규식의 적용을 하지 않았다.
// --> Data에 대한 정제가 되어있지 않으면 어디서 무슨문제가 발생할지 모른다.
// --> 실제로 파일에는 white space뿐만아니라, 다양한 구분자들이 존재한다. ( ' , :, 등등... )

var re = /[\u0000-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007F—]+/g;
// 유니코드 표 참고, 특수문자를 없애기위한 정규표현식이다.
// s+ : 스페이스가 하나 이상, g옵션 필수: g옵션이 없으면 한번만 적용이 된다.
//var arrayOfResult = result.split(' '); // 얘는 스페이스하나만가지고 split하기 때문에 비효율적이다
var arrayOfResult = result.trim().replace(re,'^^').split('^^').sort(); // split해서 결과를 살펴보자

var count = 0;
var resultObj = {}; // 원소 표현 { "word" : 25 }

async.whilst(
function() { return count < arrayOfResult.length; }, // test function, 조건비교
function(callback) { // test function return하는 값이 true면 이 함수를 수행

// var wordCnt = {};
// wordCnt[arrayOfResult[count]] = 0;

var word = arrayOfResult[count];

if(typeof(resultObj[word])==='undefined'){
resultObj[word] = 1;
count++;
process.nextTick(function() {
callback(null, resultObj);
});

} else {
resultObj[word]++;
count++;
process.nextTick(function() {
callback(null, resultObj); // 다음 콜백에 count를 넘겨준다.
});
}
},
function(err, result) {
var writer = fs.createWriteStream('wordcount_result.txt');
var strResult = JSON.stringify(result);
writer.write(strResult, function(err){
console.log('saved!!!');
});

}
);
});


<파일을 로드해서 단어 읽기(3) - 재성's 심폐소생>

// 일관리 모듈 호출하기
var fs = require('fs');
// 경로 관리 모듈 호출하기
var path = require('path');
// async 모듈 호출하기
var async = require('async');

var filePath = path.join(__dirname, '4300-0.txt');
var inputStr = "";

var reader = fs.createReadStream(filePath);

//on할 때 data 이벤트가 발생하면 함수가 실행이 됨.
reader.on('data', function(chunk) {
inputStr += chunk.toString();
});

var result = {};

reader.on('end', function () {
var rexp = /[\u0000-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007FI—]+/g;
var strArr = inputStr.trim().replace(rexp, '^').split("^").sort();

async.map(strArr, function(item, callback) {
process.nextTick(function() {
var result = { };
result[item] = 0;
callback(null, result);
});
}, function (err, results) {
if(err) {
console.log(err);
} else {
var obj = {};
var count = 0;
async.each(results, function(item, callback) {
if( obj[strArr[count]] === undefined) obj[strArr[count]] = 1;
else obj[strArr[count]]++;
count++;
callback(null);
}, function(err) {
if (err) {
console.log('error');
}
else {
console.log(obj);
}
})
}
});
});


728x90
반응형
Comments