http://proinlab.com/archives/2086


Promise.values = [];
Promise.id = 0;
Promise.exec = (promise)=> {
    let thisId = Promise.id;
    if(promise) {
        promise.then((data)=> {
            Promise.values[thisId] = data;
            resolve(data);
        });
        Promise.id++;
        return promise;
    }
    Promise.id = 0;
    return new Promise((resolve)=> resolve());
}

let A = (arg1, arg2)=> new Promise((resolve)=> {
    console.log('A Executed');
    setTimeout(()=> {
        resolve({result: arg1 + arg2});
    }, 500);
});

let B = (arg1, arg2)=> new Promise((resolve)=> {
    console.log('B Executed');
    setTimeout(()=> {
        resolve({result: arg1 - arg2});
    }, 500);
});

let C = (arg1, arg2)=> new Promise((resolve)=> {
    console.log('C Executed');
    setTimeout(()=> {
        resolve({result: arg1 * arg2});
    }, 500);
});

Promise.exec()
    .then(()=> Promise.exec(A(1, 2)))
    .then((data)=> Promise.exec(B(data.result, 4)))
    .then((data)=> Promise.exec(C(Promise.values[0].result, Promise.values[1].result)))
    .then((data)=> {
        // Promise A result
        console.log('A', Promise.values[0]);
        // Promise B result
        console.log('B', Promise.values[1]);
    // Promise C result
        console.log('C', data); // or console.log(value[2]);
    });


블로그 이미지

칩사마코더

,

Node.js의 비동기 반복 패턴 - 2 부

이것은 이전 기사 "비동기 반복 패턴"의 후속 조치입니다.

최신 피드백은 훌륭했으며 일부 수정 및 의견은 저에게 전달되었습니다.

또한, 일부 node.js 증오는 비동기 IO를 처리하는 데 필요한 몇 번 추가 된 복잡성으로 인해 확산되었습니다. 비동기 IO를 처리하는 것에 대한 두려움을 퍼트 리고이를 처리하는 방법에 대한 나의 견해를 모으고 전파하려는 의도는 아닙니다. 제 견해로는, 무위험 주의자는 좋으며 여기에 머물러 있으려면 그것을 포용하는 법을 배워야합니다.

그러나 첫째, 수정 :

Doh!

일부 독자들은 비동기 IO 작업을 호출하여 스택에서 이미 분리 중이므로 serialize_timeout.js 버전 (setTimeout을 사용하여 스택에서 분리하는 부분)이 필요하지 않다는 경고를 받았습니다.

너 맞아.

사과와 오렌지 - 공정한

node.js IO 프로그래밍과 "정상적인"블로킹 프로그래밍을 비교하려고한다면, 공정하고 합당한 두 객체를 비교해 보겠습니다.

필자의 견해로, IO API를 차단하지 않는 IO API와 구문을 비교하는 것은 공정하지 못합니다. 차단을 사용하면 훨씬 많은 작업을 수행 할 수 있기 때문입니다. 두 가지를 모두 비교하려면 node.js 솔루션과 차단 세계의 다음 솔루션을 비교해야합니다.

비 차단 입출력은 백그라운드에서 많은 입출력 작업을 수행 할 수 있기 때문에 차단 세계에서 동일한 기능을 비교하는 것이 타당합니다.

블로킹 세계에서 똑같은 동작을하기 위해서는 먼저 스레드 풀을 가지고 있어야합니다. 아니요, 각 IO 작업에 대해 새 스레드를 새로 만들지 않아도됩니다. node.js가 해당 오버 헤드를 없애기 때문입니다.

그런 다음 각 IO 작업을 스레드 풀의 새 스레드에 할당해야합니다.

그런 다음 주 스레드는 그 중 하나에서 완료 신호를 기다리는 것을 차단합니다.

각 스레드는 모든 작업이 언제 완료되는지를 알기 위해 전역 완료 카운터를 유지해야합니다. 그리고 예, 스레드 액세스를 해당 메모리에 동기화해야합니다.

한 스레드가 모든 작업이 완료되었음을 감지하면 차단 해제를 위해 대기중인 주 스레드에 알립니다. 제 의견으로는 간단하지 않습니다.

공동 루틴, 연속체, 파이버로 협업 멀티 태스킹을 호출 할 수도 있습니다. 단순화 될 것입니다. 카운터에 대한 액세스를 동기화 할 필요는 없지만 여러 컨텍스트를 관리해야합니다. 또한, 내 생각에 단순하지.

추상화

또한이 기사는 기본 패턴과 그 결과를 폭로하는 데 도움이되었습니다. 일상적인 프로그래머는 이러한 복잡성을 처리 할 필요가 없습니다. 그래서 일부 추상화가 고안되었습니다.

다음은 그 중 하나입니다.

단계

단계는 Tim Caswell의 흐름 제어 라이브러리입니다. 그것은 쉬운 방법으로 체이닝 콜백을 허용합니다.

예를 들어 async라고하는 함수가 있다고 가정 해 봅시다. 비동기 IO를 시뮬레이션하여 데이터베이스 상호 작용에서 벗어나게합니다.

function async(i, callback) {
  timeout = Math.round(Math.random() * 3000);
  setTimeout(function() {
    console.log(i + ' is done');
    callback();
  }, timeout);
}

다음으로 npm을 사용하여 단계를 설치해야합니다.

$ npm install step

그런 다음 데이터베이스에 10 개의 요소를 병렬로 삽입해야합니다.

var Step = require('step');

var collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

Step(

  function insertAll() {
    var self = this;
    collection.forEach(function(element) {
      async(element, self.parallel());
    });
  },
  function finalize(err) {
    if (err) { console.log(err);return;}
    console.log('done with no problem');
  }
);

당신은 단순히 2 개의 기능을 가진 step을 사용할 것입니다.

처음에는 모든 요소를 ​​병렬로 삽입합니다. 콜백에 this.parallel ()을 전달하면 병렬 요청을 처리하는 콜백을 생성하는 방법입니다.

블로그 이미지

칩사마코더

,

Node.js의 비동기 반복 패턴

node.js에서 IO를 수행 할 때처럼 비동기 적으로 프로그래밍 할 때 특히 이해하기 어려운 패턴이 있습니다.

예를 들어 다음 루틴을 프로그래밍해야한다고 가정 해 보겠습니다.

데이터베이스에 개체 컬렉션을 삽입 한 다음 완료되면 콜백을 호출합니다. 그래서 이것을 동기식으로 작성해야한다면 다음과 같이 할 수 있습니다 :

function insertCollection(collection) {
  for(var i = 0; i < collection.length; i++) {
    db.insert(collection[i]);
  }
}

따라서 node.js를 사용하기 때문에 db.insert가 비동기 일 가능성이 높습니다. 이것을 비동기 함수로 바꾸어야합니다.

나는이 같은 명백하게 잘못된 implents를 보았다 :

function insertCollection(collection, callback) {
  for(var i = 0; i < collection.length; i++) {
    db.insert(collection[i], function(err) {
      if (err) {
        throw err;
      }
    });
  }
  callback();
}

이 문제는 명백합니다. 콜백은 백그라운드에서 모든 db.inserts를 시작한 직후에 호출되며 완료 할 기회를 남기지 않습니다. 콜백이 호출되면 삽입이 종료되지 않습니다.

또 다른 접근법은 다음과 같습니다.

function insertCollection(collection, callback) {
  for(var i = 0; i < collection.length; i++) {
    (function(i) {
      db.insert(collection[i], function(err) {
        if (err) {
          callback(err);
          return;
        }
        if (i == (collection.length - 1)) {
          callback();
        }
      });
    })(i);
  }
}

따라서 "마지막 삽입물이 콜백 할 때 전화해야합니다"라고 생각할 유혹이 있습니다. 그러나 이것은 틀린 것입니다. 마지막 한 콜백이 실행될 때 첫 번째 삽입이 여전히 실행 중일 수 있습니다. 너는 결코 알지 못한다.

가장 안전한 방법은 다음과 같이하는 것입니다.

function insertCollection(collection, callback) {
  var inserted = 0;
  for(var i = 0; i < collection.length; i++) {
    db.insert(collection[i], function(err) {
      if (err) {
        callback(err);
        return;
      }
      if (++inserted == collection.length) {
        callback();
      }
    });
  }
}

모든 삽입이 콜백되었을 때만 콜백해야합니다.

직렬화

때로는 흐름 및 / 또는 실행 순서를 제어하려고합니다.

이 경우 삽입물을 완벽하게 정렬하거나 오류가 발생하면 삽입을 중단하여보다 쉽게 ​​복구 할 수 있습니다.

이 경우 다음과 같이 할 수 있습니다.

function insertCollection(collection, callback) {
  var coll = collection.slice(0); // clone collection
  (function insertOne() {
    var record = coll.splice(0, 1)[0]; // get the first record of coll and reduce coll by one
    db.insert(record, function(err) {
      if (err) { callback(err); return }
      if (coll.length == 0) {
        callback();
      } else {
        insertOne();
      }
    }
  })();
}

여기에서는 꼬리 재귀를 사용하여 레코드를 계속 삽입합니다.

이 예제에는 한 가지 문제가 있습니다. 스택을 사용하므로 컬렉션이 너무 크면 스택이 끊어 질 수 있습니다.

이 문제에 대한 한 가지 해결책은 재귀 할 때 스택을 포기하는 것입니다. 그리고 당신은 0의 timeout 값을 가진 setTimeout을 사용하여 그것을 할 수 있습니다. 스택이 unwind 된 후에 inner 함수가 호출되도록합니다 :

function insertCollection(collection, callback) {
  var coll = collection.slice(0); // clone collection
  (function insertOne() {
    var record = coll.splice(0, 1)[0]; // get the first record of coll and reduce coll by one
    db.insert(record, function(err) {
      if (err) { callback(err); return }
      if (coll.length == 0) {
        callback();
      } else {
        setTimeout(insertOne, 0);
      }
    }
  })();
}

후속 조치

후속 기사 Node.js의 비동기 반복 패턴보기 - 2 부

최신 정보:

또한 (Tim Caswell이 지적한 바와 같이) 콜백으로 끝나는 대신 이벤트 루프로 예외가 되돌아 가지 않는 것이 중요합니다. 따라서 db.insert 또는 다른 외부 함수 호출을 래핑해야합니다. 마지막 예는 다음과 같습니다.

function insertCollection(collection, callback) {
  var coll = collection.slice(0); // clone collection
  (function insertOne() {
    var record = coll.splice(0, 1)[0]; // get the first record of coll and reduce coll by one
    try {
      db.insert(record, function(err) {
        if (err) { callback(err); return }
        if (coll.length == 0) {
          callback();
        } else {
          insertOne();
        }
      }
    } catch (exception) {
      callback(exception);
    }
  })();
}


블로그 이미지

칩사마코더

,

forever npm start

node js 2017. 3. 21. 21:04

forever start -c "npm start" ./

블로그 이미지

칩사마코더

,

// var seed_money  = parseInt($('#seed_money').val());

// var start_money = parseInt($('#start_money').val());

var seed_money  = ($('#seed_money').val());

var start_money = ($('#start_money').val());


자바스크립트 연산전에 형변환을 해야 버벅거림이 없음


노드JS에서는 형변환없이도 바로 처리가 되는데

왜 이러지?

블로그 이미지

칩사마코더

,
curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
yum -y install nodejs


블로그 이미지

칩사마코더

,

보통 node를 이용해 스크립트를 실행하는 방법은 node 명령어 뒤에 javascript 파일을 적어주는 것입니다. 

 node sample.js

이런 식으로 node를 사용하다보면 불편한 점이 한 둘이 아니죠. 소스코드가 수정되면 프로세스를 죽였다 살려줘야 하고, 죽일 때에도 node 프로세스를 죽이기 위해 프로세스 id를 찾는 수고로움을 치루어야 합니다. 이에 손쉽게 수정된 소스 코드를 반영하여 재실행하는 방법과 프로세스가 문제가 발생하여 죽더라도 자동으로 재시작 되는 방법, 그리고 스크립트를 빠르게 시작하고 종료하는 방법에 대해 알아봅시다.

  1. nodemon
    nodemon은 node 스크립트가 수정된 것을 감지하여 자동으로 재시작시켜주는 애플리케이션입니다. 한참 개발을 진행 중일때 없어서는 안될 유용한 프로그램이죠.
    • 설치:
      npm install nodemon -g
      -g 옵션을 주어 전역적으로 설치 할 수 있습니다. 이 경우 단일 프로젝트로 제한하지 않고 어느 프로젝트에서나 사용 할 수 있겠죠. sudo로 관리자 권한이 필요 할 수 있습니다.
    • 실행:
      nodemon sample.js
    • 공식 사이트: 
      https://github.com/remy/nodemon

  2. forever 
    forever는 nodemon에 비해 더욱 다양한 기능을 가지고 있습니다. 노드를 쉽게 실행, 종료 시키고 기본으로 로그 출력을 지원하며, 애플리케이션이 종료될 때에도 자동으로 재시작시켜줍니다.
    • 설치:
      npm install forever -g
    • 사용:
      forever start sample.js
      forever stop sample.js
      forever restart sample.js
      forever list

      이외에도 다양한 명령어가 있습니다만, 이 정도만 알아도 사용하는데 무리가 없을거에요. 이 명령어 조합은 자주 사용하는 것 위주로 쉘 스크립트를 만들어 사용하면 더욱 편리합니다.
    • 공식 사이트: 
      https://github.com/nodejitsu/forever


블로그 이미지

칩사마코더

,

var casper = require('casper').create({

    logLevel: "error",

    verbose: true

});


var url = "http://ladder.named.com/main.php";

var fs = require('fs');

var path = 'output2.txt';


casper.start(url, function() {


    console.log("크롤링 시작");


    var content = JSON.parse(fs.read(path));

    console.log("불러온 쿠키: " + JSON.stringify(content));

    

    console.log("현재 쿠키: " + JSON.stringify(phantom.cookies));

    

    phantom.cookies = content;

    console.log("저장된 쿠키: " + JSON.stringify(phantom.cookies));


});


casper.run(function() {

    this.close();

});


핵심포인트

phantom.cookies

블로그 이미지

칩사마코더

,

var path = 'output1.txt';

var save = 'output2.txt';

var fs = require('fs');



fs.stat(path, function(err, stats) {

if (stats.isFile(path)) {

        console.log('쿠키파일 존재');

    }

});

   

블로그 이미지

칩사마코더

,

   child.stdout.on("data", function(data) {

        i= i + 1;

        console.log(i + "번째");

        result += data;

       var str = data;

       console.log(`${str.length} characters, ` +

            `${Buffer.byteLength(str, 'utf8')} bytes`);

    });



console.log(`${str.length} characters, ` +`${Buffer.byteLength(str, 'utf8')} bytes`);

'node js' 카테고리의 다른 글

node.js 애플리케이션을 쉽고 빠르게 실행/종료하기  (0) 2016.10.20
casperjs 쿠키 저장 읽어오기  (0) 2016.09.23
파일 존재 여부 확인  (0) 2016.09.23
spawn 자식프로세스 종료  (0) 2016.09.22
PHP nodejs ajax 연동  (0) 2016.08.26
블로그 이미지

칩사마코더

,