콜백이 돌아올 때까지 "기다리는" 방법은?
아래 예와 같이 간단한 콜백을 사용하는 경우:
test() {
api.on( 'someEvent', function( response ) {
return response;
});
}
비동기식 / wait를 사용하도록 기능을 변경하려면 어떻게 해야 합니까?구체적으로 'someEvent'가 한 번, 한 번만 호출이 보장된다고 가정할 때, 다음과 같이 콜백이 실행될 때까지 함수 테스트가 반환되지 않는 비동기 함수이면 좋겠습니다.
async test() {
return await api.on( 'someEvent' );
}
async/await
마법이 아닙니다.비동기 기능은 당신을 위한 약속을 풀 수 있는 기능이므로 당신은 다음이 필요할 것입니다.api.on()
약속을 이행할 수 있게 해주는 거죠이와 같은 것:
function apiOn(event) {
return new Promise(resolve => {
api.on(event, response => resolve(response));
});
}
그리고나서
async function test() {
return await apiOn( 'someEvent' ); // await is actually optional here
// you'd return a Promise either way.
}
하지만 이 또한 거짓말입니다. 왜냐하면 비동기 기능은 약속 자체를 반환하므로 실제로 가치를 얻을 수 없기 때문입니다.test()
, 대신 다음과 같이 사용할 수 있는 가치에 대한 약속(Promise for a value.
async function whatever() {
// snip
const response = await test();
// use response here
// snip
}
간단한 해결책이 없다는 것이 짜증나고, 포장.return new Promise(...)
도망치긴 하지만, 그를 이용한 적절한 해결책을 찾았습니다.util.promisify
(actually 역시 같은 포장을 하고, 더 보기 좋아 보입니다.)
function voidFunction(someArgs, callback) {
api.onActionwhichTakesTime(someMoreArgs, (response_we_need) => {
callback(null, response_we_need);
});
}
위 기능은 아직 아무것도 반환하지 않습니다.우리는 그것을 돌려줄 수 있습니다.Promise
의response
전해진callback
다음을 수행하여
const util = require('util');
const asyncFunction = util.promisify(voidFunction);
이제 우리는 실제로 할 수 있습니다.await
그callback
.
async function test() {
return await asyncFunction(args);
}
사용할 때 몇 가지 규칙util.promisify
- 그
callback
앞으로 일어날 함수의 마지막 논쟁임에 틀림없습니다.promisify
- 콜백 추정치는 다음과 같은 형식이어야 합니다.
(err, res) => {...}
재미있는 것은 우리가 무엇이 무엇인지를 구체적으로 쓸 필요가 없다는 것입니다.callback
사실은 그렇습니다.
비동기/await은 마법입니다.함수를 만들 수 있습니다.asPromise
이런 상황에 대처하는 방법:
function asPromise(context, callbackFunction, ...args) {
return new Promise((resolve, reject) => {
args.push((err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
if (context) {
callbackFunction.call(context, ...args);
} else {
callbackFunction(...args);
}
});
}
필요할 때 사용할 수 있습니다.
async test() {
return await this.asPromise(this, api.on, 'someEvent');
}
arg의 수는 가변적입니다.
const getprice = async () => {
return await new Promise((resolve, reject) => {
binance.prices('NEOUSDT', (error, ticker) => {
if (error) {
reject(error)
} else {
resolve(ticker);
}
});
})}
router.get('/binanceapi/price', async function (req, res, next) {
res.send(await binanceAPI.getprice());});
콜백 없이도 이를 달성할 수 있습니다. 여기서는 콜백 대신 약속 비동기를 사용하는 방법을 사용합니다.그리고 여기서는 오류를 처리하는 두 가지 방법을 설명했습니다.
clickMe = async (value) => {
// begin to wait till the message gets here;
let {message, error} = await getMessage(value);
// if error is not null
if(error)
return console.log('error occured ' + error);
return console.log('message ' + message);
}
getMessage = (value) => {
//returning a promise
return new Promise((resolve, reject) => {
setTimeout(() => {
// if passed value is 1 then it is a success
if(value == 1){
resolve({message: "**success**", error: null});
}else if (value == 2){
resolve({message: null, error: "**error**"});
}
}, 1000);
});
}
clickWithTryCatch = async (value) => {
try{
//since promise reject in getMessage2
let message = await getMessage2(value);
console.log('message is ' + message);
}catch(e){
//catching rejects from the promise
console.log('error captured ' + e);
}
}
getMessage2 = (value) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(value == 1)
resolve('**success**');
else if(value == 2)
reject('**error**');
}, 1000);
});
}
<input type='button' value='click to trigger for a value' onclick='clickMe(1)' />
<br/>
<input type='button' value='click to trigger an error' onclick='clickMe(2)' />
<br/>
<input type='button' value='handling errors with try catch' onclick='clickWithTryCatch(1)'/>
<br/>
<input type='button' value='handling errors with try catch' onclick='clickWithTryCatch(2)'/>
반환 약속 함수를 정의합니다.
export const callbackf = (f, ...args) => new Promise((resolve, reject) => {
f(...args, (error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
필요한 곳에서 약속을 기다립니다. arg1, arg2, ...는 콜백 함수 인수입니다.
await callbackf(yourCallbackFunction, arg1, arg2, arg3, argN)
언급URL : https://stackoverflow.com/questions/37104199/how-to-await-for-a-callback-to-return
'code' 카테고리의 다른 글
'Method' get_을 수정하는 방법정보'를 'Oracle' 유형으로 입력합니다.EntityFrameworkCore에는 구현이 없습니다.' (0) | 2023.09.25 |
---|---|
자동 레이아웃을 프로그래밍 방식으로 사용하여 수퍼뷰와 동일한 너비 및 높이? (0) | 2023.09.25 |
Python 3.0,3.1,3.2의 "ValueError: 0 length 필드 이름 형식" 오류 (0) | 2023.09.20 |
잘못된 범위: publish_actions, manage_pages, publish_pages, user_managed_groups, user_posts, user_phots (0) | 2023.09.20 |
메모장++:파일 로드 시 Language를 Xml로 자동 설정하는 방법 (0) | 2023.09.20 |