[javascript] Node.js 용 비동기 함수를 작성하는 방법

나는 정확히 어떻게 비동기 함수를 작성해야하는지에 대해 연구하려고했습니다. 많은 문서를 훑어 본 후에도 여전히 명확하지 않습니다.

Node 용 비동기 함수를 어떻게 작성합니까? 오류 이벤트 처리를 올바르게 구현하려면 어떻게해야합니까?

내 질문을하는 또 다른 방법은 다음과 같습니다. 다음 기능을 어떻게 해석해야합니까?

var async_function = function(val, callback){
    process.nextTick(function(){
        callback(val);
    });
};

또한 SO ( “node.js에서 비 차단 비동기 함수를 어떻게 생성합니까?”) 에서이 질문이 흥미 롭다는 것을 발견했습니다. 아직 답을 얻지 못한 것 같습니다.



답변

비동기 IO와 비동기 함수를 혼동하는 것 같습니다. node.js는 비 차단 IO가 더 낫기 때문에 비동기 비 차단 IO를 사용합니다. 그것을 이해하는 가장 좋은 방법은 Ryan Dahl의 비디오를 보는 것입니다.

Node 용 비동기 함수를 어떻게 작성합니까?

정상적인 함수를 작성하기 만하면됩니다. 유일한 차이점은 바로 실행되지 않고 콜백으로 전달된다는 것입니다.

오류 이벤트 처리를 올바르게 구현하려면 어떻게해야합니까?

일반적으로 API는 첫 번째 인수로 err이있는 콜백을 제공합니다. 예를 들면

database.query('something', function(err, result) {
  if (err) handle(err);
  doSomething(result);
});

일반적인 패턴입니다.

또 다른 일반적인 패턴은 on('error'). 예를 들면

process.on('uncaughtException', function (err) {
  console.log('Caught exception: ' + err);
});

편집하다:

var async_function = function(val, callback){
    process.nextTick(function(){
        callback(val);
    });
};

위의 함수는 다음과 같이 호출 될 때

async_function(42, function(val) {
  console.log(val)
});
console.log(43);

42콘솔에 비동기 적으로 인쇄 합니다. 특히 process.nextTick현재 이벤트 루프 호출 스택이 비어있는 후에 발생합니다. 즉, 호출 스택 후 비어 async_functionconsole.log(43)실행했다. 따라서 43 다음에 42를 인쇄합니다.

이벤트 루프에 대해 읽어야 할 것입니다.


답변

콜백을 전달하는 것만으로는 충분하지 않습니다. 예를 들어 함수를 비 동기화하려면 settimer를 사용해야합니다.

예 : 비동기 함수가 아닙니다.

function a() {
  var a = 0;
  for(i=0; i<10000000; i++) {
    a++;
  };
  b();
};

function b() {
  var a = 0;
  for(i=0; i<10000000; i++) {
    a++;
  };
  c();
};

function c() {
  for(i=0; i<10000000; i++) {
  };
  console.log("async finished!");
};

a();
console.log("This should be good");

위의 예제를 실행한다면 이것은 좋을 것입니다. 이러한 기능이 작동을 마칠 때까지 기다려야합니다.

의사 다중 스레드 (비동기) 함수 :

function a() {
  setTimeout ( function() {
    var a = 0;
    for(i=0; i<10000000; i++) {
      a++;
    };
    b();
  }, 0);
};

function b() {
  setTimeout ( function() {
    var a = 0;
    for(i=0; i<10000000; i++) {
      a++;
    };
    c();
  }, 0);
};

function c() {
  setTimeout ( function() {
    for(i=0; i<10000000; i++) {
    };
    console.log("async finished!");
  }, 0);
};

a();
console.log("This should be good");

이것은 완전히 비동기 적입니다. 이것은 비동기가 완료되기 전에 작성 될 것입니다.


답변

당신은 이것을 봐야한다 : Node Tuts 에피소드 19-비동기 반복 패턴

귀하의 질문에 답해야합니다.


답변

함수가 약속을 반환한다는 것을 알고 있다면 JavaScript에서 새로운 async / await 기능을 사용하는 것이 좋습니다. 구문을 동 기적으로 보이게하지만 비동기 적으로 작동합니다. async함수에 키워드를 추가하면 await해당 범위에서 약속 할 수 있습니다 .

async function ace() {
  var r = await new Promise((resolve, reject) => {
    resolve(true)
  });

  console.log(r); // true
}

함수가 promise를 반환하지 않으면 정의한 새 promise로 래핑 한 다음 원하는 데이터를 해결하는 것이 좋습니다.

function ajax_call(url, method) {
  return new Promise((resolve, reject) => {
    fetch(url, { method })
    .then(resp => resp.json())
    .then(json => { resolve(json); })
  });
}

async function your_function() {
  var json = await ajax_call('www.api-example.com/some_data', 'GET');
  console.log(json); // { status: 200, data: ... }
}

결론 : 약속의 힘을 활용하십시오.


답변

이것을 시도하면 노드와 브라우저 모두에서 작동합니다.

isNode = (typeof exports !== 'undefined') &&
(typeof module !== 'undefined') &&
(typeof module.exports !== 'undefined') &&
(typeof navigator === 'undefined' || typeof navigator.appName === 'undefined') ? true : false,
asyncIt = (isNode ? function (func) {
  process.nextTick(function () {
    func();
  });
} : function (func) {
  setTimeout(func, 5);
});


답변

node.js에 대한 그러한 작업에 너무 많은 시간을 처리했습니다. 나는 주로 프론트 엔드 사람입니다.

모든 노드 메서드가 비동기 적으로 콜백을 처리하고이를 Promise로 변환하는 것이 처리하는 것이 더 낫기 때문에 이것이 매우 중요하다고 생각합니다.

나는 가능한 결과를 더 간결하고 읽기 쉽게 보여주고 싶습니다. 비동기로 ECMA-6을 사용하면 다음과 같이 작성할 수 있습니다.

 async function getNameFiles (dirname) {
  return new Promise((resolve, reject) => {
    fs.readdir(dirname, (err, filenames) => {
      err !== (undefined || null) ? reject(err) : resolve(filenames)
    })
  })
}

(undefined || null)위한 REPL 도 미정의 작업을 이용하여 (읽기 이벤트 프린트 루프) 시나리오.


답변