비동기 nodejs 모듈 내보내기
모듈 내보내기를 구성하는 가장 좋은 방법이 무엇인지 궁금합니다. 아래 예에서 "async.function"은 FS 또는 HTTP 요청 일 수 있으며 예를 위해 단순화되었습니다.
다음은 예제 코드 (asynmodule.js)입니다.
var foo = "bar"
async.function(function(response) {
foo = "foobar";
// module.exports = foo; // having the export here breaks the app: foo is always undefined.
});
// having the export here results in working code, but without the variable being set.
module.exports = foo;
비동기 콜백이 실행 된 후에 만 모듈을 내보내려면 어떻게해야합니까?
실제 사용 사례에 대한 빠른 메모 편집 : fs.exists () 콜백에서 nconf ( https://github.com/flatiron/nconf ) 를 구성하는 모듈을 작성하고 있습니다 (즉, 구성 파일을 구문 분석하고 nconf 설정).
foo
선언이 내부에있는 동안 함수 외부에 있기 때문에 내보내기가 작동하지 않습니다 . 그러나 내보내기를 내부에 넣으면 모듈을 사용할 때 내보내기가 정의되었는지 확인할 수 없습니다.
비동기 시스템으로 작업하는 가장 좋은 방법은 콜백을 사용하는 것입니다. 콜백을 가져 오려면 콜백 할당 메서드를 내보내고 비동기 실행시 호출해야합니다.
예:
var foo, callback;
async.function(function(response) {
foo = "foobar";
if( typeof callback == 'function' ){
callback(foo);
}
});
module.exports = function(cb){
if(typeof foo != 'undefined'){
cb(foo); // If foo is already define, I don't wait.
} else {
callback = cb;
}
}
다음 async.function
은 비동기 호출을 상징하는 자리 표시 자입니다.
메인에서
var fooMod = require('./foo.js');
fooMod(function(foo){
//Here code using foo;
});
다중 콜백 방법
모듈을 두 번 이상 호출해야하는 경우 콜백 배열을 관리해야합니다.
var foo, callbackList = [];
async.function(function(response) {
foo = "foobar";
// You can use all other form of array walk.
for(var i = 0; i < callbackList.length; i++){
callbackList[i](foo)
}
});
module.exports = function(cb){
if(typeof foo != 'undefined'){
cb(foo); // If foo is already define, I don't wait.
} else {
callback.push(cb);
}
}
다음 async.function
은 비동기 호출을 상징하는 자리 표시 자입니다.
메인에서
var fooMod = require('./foo.js');
fooMod(function(foo){
//Here code using foo;
});
약속 방법
Promise를 사용하여 해결할 수도 있습니다. 이 메서드는 Promise의 디자인에 따라 다중 호출을 지원합니다.
var foo, callback;
module.exports = new Promise(function(resolve, reject){
async.function(function(response) {
foo = "foobar"
resolve(foo);
});
});
다음 async.function
은 비동기 호출을 상징하는 자리 표시 자입니다.
메인에서
var fooMod = require('./foo.js').then(function(foo){
//Here code using foo;
});
Promise 문서 참조
또 다른 접근 방식은 변수를 개체 내부에 래핑하는 것입니다.
var Wrapper = function(){
this.foo = "bar";
this.init();
};
Wrapper.prototype.init = function(){
var wrapper = this;
async.function(function(response) {
wrapper.foo = "foobar";
});
}
module.exports = new Wrapper();
이니셜 라이저에 오류가있는 경우 최소한 콜백을 중단하는 대신 초기화되지 않은 값을 얻습니다.
약속을 사용하여 ES6 답변 :
const asyncFunc = () => {
return new Promise((resolve, reject) => {
// Where someAsyncFunction takes a callback, i.e. api call
someAsyncFunction(data => {
resolve(data)
})
})
}
export default asyncFunc
...
import asyncFunc from './asyncFunc'
asyncFunc().then(data => { console.log(data) })
또는 Promise 자체를 직접 반환 할 수 있습니다.
const p = new Promise(...)
export default p
...
import p from './asyncModule'
p.then(...)
Promise를 사용할 수도 있습니다.
some-async-module.js
module.exports = new Promise((resolve, reject) => {
setTimeout(resolve.bind(null, 'someValueToBeReturned'), 2000);
});
main.js
var asyncModule = require('./some-async-module');
asyncModule.then(promisedResult => console.log(promisedResult));
// outputs 'someValueToBeReturned' after 2 seconds
다른 모듈에서도 동일한 일이 발생할 수 있으며 예상대로 해결됩니다.
in-some-other-module.js
var asyncModule = require('./some-async-module');
asyncModule.then(promisedResult => console.log(promisedResult));
// also outputs 'someValueToBeReturned' after 2 seconds
promise 객체는 한 번 생성 된 다음 노드별로 캐시됩니다. 각각 require('./some-async-module')
은 동일한 개체 인스턴스를 반환합니다 (이 경우 Promise 인스턴스).
ES7 접근 방식은 module.exports에서 즉시 호출되는 비동기 함수 입니다.
module.exports = (async function(){
//some async initiallizers
//e.g. await the db module that has the same structure like this
var db = await require("./db");
var foo = "bar";
//resolve the export promise
return {
foo
};
})()
나중에 await로 필요할 수 있습니다.
(async function(){
var foo = await require("./theuppercode");
console.log(foo);
})();
다른 답변은 부분 답변으로 보였고 저에게 효과가 없었습니다. 이것은 다소 완전한 것 같습니다.
some-module.js
var Wrapper = function(){
this.callbacks = [];
this.foo = null;
this.init();
};
Wrapper.prototype.init = function(){
var wrapper = this;
async.function(function(response) {
wrapper.foo = "foobar";
this.callbacks.forEach(function(callback){
callback(null, wrapper.foo);
});
});
}
Wrapper.prototype.get = function(cb) {
if(typeof cb !== 'function') {
return this.connection; // this could be null so probably just throw
}
if(this.foo) {
return cb(null, this.foo);
}
this.callbacks.push(cb);
}
module.exports = new Wrapper();
main.js
var wrapper = require('./some-module');
wrapper.get(function(foo){
// foo will always be defined
});
main2.js
var wrapper = require('./some-module');
wrapper.get(function(foo){
// foo will always be defined in another script
});
참고 URL : https://stackoverflow.com/questions/20238829/asynchronous-nodejs-module-exports
'developer tip' 카테고리의 다른 글
로컬로 설치된 경우 관련없는 패키지 (0) | 2020.12.05 |
---|---|
배우 자체에서 Akka 배우의 이름을 어떻게 얻을 수 있습니까? (0) | 2020.12.05 |
HashMap과 사전 ADT의 차이점 (0) | 2020.12.05 |
Javascript는 클래스를 확장합니다. (0) | 2020.12.05 |
JavaScript에서 ASP.NET MVC 작업 메서드 호출 (0) | 2020.12.04 |