๋ฐฉ์ ์๋ ์ฝ๋ผ๋ฆฌ ์ค ํ๋๋ Node ๋ฐ Chrome์ ์ ๊ณต๋๊ณ ๊ณง ๋ค๋ฅธ ๋ชจ๋ ์ฃผ์ ๋ธ๋ผ์ฐ์ ์ ์ ์ฉ๋ ์๋ก์ด async
/ await
์ง์์
๋๋ค. ์ ๋ Async๊ฐ async
/ await
์ธ๊ณ์์ ๋ฌด์์ ํ ์ ์๋์ง ์๊ฐํด ์์ต๋๋ค.
ํ์ฌ asyncify
๋ก ๋ํํ์ฌ async
ํจ์๋ฅผ ์กฐ์ ํ ์ ์์ต๋๋ค. async
ํจ์๋ ๋ณธ์ง์ ์ผ๋ก Promise๋ฅผ ๋ฐํํ๋ ํจ์์ผ ๋ฟ์ด๋ฏ๋ก ์ด์ ์ด๋ํฐ๋ ์ด๋ฅผ ์ฝ๋ฐฑ ์คํ์ผ ํจ์๋ก ์ฝ๊ฒ ๋ณํํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ๋ค์ ํฐ๋ฌด๋์๋ ๋ชจ์์ผ๋ก ์ด์ด์ง๋๋ค.
async.mapLimit(arr, 10, async.asyncify(async (val) => {
let foo = await doSomething(val);
//...
return bar;
}), done);
๊ทธ๋ฌ๋ async
๊ธฐ๋ฅ์ ๋ํ ์ฌ์์ ๊ธฐ๋ฅ ์ค ํ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction"
์ด๊ฒ์ (๋ค์ดํฐ๋ธ) async
ํจ์๋ฅผ ์ฝ๊ฒ ๊ฐ์งํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ์๋์ผ๋ก asyncify
ํ ์ ์์ต๋๋ค. ์์ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
async.mapLimit(arr, 10, async (val) => {
let foo = await doSomething(val);
//...
return bar;
}, done);
... ํจ์ฌ ๋ ์์ฐ์ค๋ฝ๊ฒ ํ๋ฅด๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ํ ์ฝ๋ฐฑ์ ๊ณ์ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฌ์ฉ์๊ฐ await
๊ฒฐ๊ณผ๋ฅผ ์ํ๋ฉด promisify
ํจ์ ๋๋ pify
์ ์ฒด์ ์ผ๋ก ๋น๋๊ธฐํํด์ผ ํฉ๋๋ค.
let result = await pify(async.mapLimit)(arr, 10, async (val) => {
let foo = await doSomething(val);
//...
return bar;
});
async
ํจ์๋ฅผ ๊ฐ์งํ๋ ์์ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ ํจ์์์๋ง ์๋ํฉ๋๋ค. Babel ํธ๋์คํ์ผ ๊ธฐ๋ฅ์ ๊ฐ์งํ ๋ฐฉ๋ฒ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์๊ธ์ ์ผ๋ก ์ฝ๋ฐฑ์ ์ ๋ฌํ์ง ์์์ผ ํ๊ธฐ ๋๋ฌธ์ ๋จ์ํ ์ฝ์์ ๋ฐํํ๋ ์ผ๋ฐ ํจ์๋ ํ์คํ ๊ฐ์งํ ์ ์์ต๋๋ค. ๊ทธ๋ ์ด๊ฒ์ด ๋งค์ฐ ํ๋์ ์ธ ํ๊ฒฝ์์ ํธ๋์คํ์ผ๋ฌ ์์ด๋ง ์๋ํ ๊ฒ์ด๋ผ๋ ์์ฒญ๋ ๊ฒฝ๊ณ ๊ฐ ์์ ๊ฒ์
๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฌ์ ํ asyncify
๋ก ์๋์ผ๋ก ๋ํํด์ผ ํฉ๋๋ค.
๋ํ ๋ง์ ๋น๋๊ธฐ ๋ฉ์๋๊ฐ async
/ await
๋ก ์ดํด๋์ง ์์ต๋๋ค. ๋๋ถ๋ถ์ ์ ์ด ํ๋ฆ ๋ฉ์๋( auto
๋ฐ queue
์ ์ธ)๋ ๊ธฐ๋ณธ ์ ์ด ํ๋ฆ ๊ตฌ์ฑ์ผ๋ก ๋ ์ฝ๊ฒ ๋ณต์ ๋ฉ๋๋ค. map
๋ฐ parallel
๋ Promise.map
๋ฐ Promise.all
๋ก ๋์ฒดํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ ํ์ ์ธ ์์ง ๊ธฐ๋ฅ๊ณผ auto
๋ฐ ๊ธฐํ ๋ช ๊ฐ์ง ๊ธฐ๋ฅ์ด ๋งค์ฐ ์ ์ฉํ ๊ฒ์
๋๋ค. (๋ํ async
ํจ์๊ฐ ์๋ autoInject
๋ ๋น๋๊ธฐ ์ ์ด ํ๋ฆ์ ๊ฟ์
๋๋ค!)
์ด ๋ฌธ์ ์ ๋ํด ์ข ๋ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค. ํ์ง๋ง ์ด๊ฒ์ด ์ด๋ป๊ฒ ์๊ฒผ๋์ง ๋ ์ ์์ํ ์ ์๋๋ก ๋ช ๊ฐ์ง ๊ธฐ์ ์ ์ธ ์ง๋ฌธ์ ํ๊ณ ์ถ์ต๋๋ค.
Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction"
๋ฅผ ํ ์ด์ ๊ฐ ์์ต๋๊น ์๋๋ฉด asyncFn[Symbol.toStringTag] === "AsyncFunction"
๋ฅผ ํ ์ ์์ต๋๊น(FF์์ ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค)?
๋๊ตฐ๊ฐ cb(err, arg)
ํ์์ ์ฝ๋ฐฑ์ ์ ๊ณตํ ๋๋ง๋ค ์ ์์ด AsyncFunction
์ธ์ง ๊ฐ์งํด์ผ ํฉ๋๋ค. ๋น๋๊ธฐ ํจ์์ธ ๊ฒฝ์ฐ promisify
๋ฅผ ์ ์ฉํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๊ทธ๋๋ก ์ฌ์ฉํฉ๋๋ค.
๋ํ ์ฃ์กํฉ๋๋ค. ์ ๋ await ์์ ๋ฅผ ๋ฐ๋ฅด์ง ์๊ณ ์์ต๋๋ค. ํจ์๊ฐ AsyncFunction
์์ ๊ฐ์งํ๋ฉด await
์ง์์ ์ด๋ ค์์ ๋ฌด์์
๋๊น?
Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction"
๋ฅผ ํ ์ด์ ๊ฐ ์์ต๋๊น ์๋๋ฉดasyncFn[Symbol.toStringTag] === "AsyncFunction"
๋ฅผ ํ ์ ์์ต๋๊น(FF์์ ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค)?
๊ทธ๊ฒ์ด ๋ฐ๋ก ํ์ค ECMA ์ฌ์ ๋ฐฉ์์
๋๋ค. ์ด๋ก ์ ์ผ๋ก ๋๊ตฐ๊ฐ asyncFn[Symbol.toStringTag]
๋ฅผ ๋ฎ์ด์ธ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋๊ตฐ๊ฐ๊ฐ cb(err, arg) ํ์์ ์ฝ๋ฐฑ์ ์ ๊ณตํ ๋๋ง๋ค ์ ์์ด AsyncFunction์ธ์ง ๊ฐ์งํด์ผ ํฉ๋๋ค. ๊ทธ๊ฒ์ด ๋น๋๊ธฐ ํจ์๋ผ๋ฉด ์ฐ๋ฆฌ๋ promisify๋ฅผ ์ ์ฉํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๊ทธ๋๋ก ์ฌ์ฉํ์ญ์์ค.
๋๋ ๋น์ ์ด ๊ทธ๊ฒ์ ์ฝ๊ฐ ๋ค๋ก ๊ฐ์ง๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฝ๋ฐฑ์ ํ์ฉํ๋ ๋ฐ๋ณต ํจ์( function(args..., callback) {}
)๋ฅผ ์๋ฝํ ๋๋ง๋ค async
ํจ์์ธ์ง ํ์ธํ ๋ค์ asyncify
$ ํจ์์ธ์ง ํ์ธํด์ผ ํฉ๋๋ค.
await
์์ ๋ Async ๋ฉ์๋๋ฅผ await
๋ก ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ ์ํํ ์์
์
๋๋ค. Async ๋ฉ์๋๊ฐ ์ฝ์์ ๋ฐํํ๊ธฐ ์์ํ๋๋ก ํด์๋ ์ ๋๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋์ผ ์๋ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ํ๋๋ก ๋๋์ญ์์ค.
#1390์์ ๊ตฌํ๋์์ต๋๋ค!
์ด๊ฒ์ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด๋ฉฐ ๋ฐฐํฌ๋ ์ฝ๋๋ฅผ ์์์์ผฐ์ต๋๋ค. ๋ฉ์ด์ ๋ฒ์ ์ ๋์ด์ง ์๊ณ ๊ทธ๋ฐ ์ผ์ ํ ๋๋ ๋ค์ ํ ๋ฒ ์๊ฐํ์ญ์์ค.
์ถ์ : ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ๊ป ํ๋ ๋ชจ๋ ํ๋ฅญํ ์์ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค ๐
์ฌ๊ฒฉ! ๊ณ ์ฅ๋ ๊ฒ. ์์ธํ ๋ด์ฉ์ด ํฌํจ๋ ํฐ์ผ์ ์์ฑํด ์ฃผ์๊ฒ ์ต๋๊น?
์ด๊ฒ์ด ์๋ํ์ง ์๋ ํ๊ฒฝ?
๊ฐ์ฌ ํด์!
2017๋
4์ 5์ผ ์์์ผ ์ค์ 10:18 Manuel Valls Fernรกndez <
[email protected]>์ ๋ค์๊ณผ ๊ฐ์ด ์ผ์ต๋๋ค.
์ด๊ฒ์ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด๋ฉฐ ๋ฐฐํฌ๋ ์ฝ๋๋ฅผ ์์์์ผฐ์ต๋๋ค. ๋ ๋ฒ ์๊ฐํ์ญ์์ค
๋ฉ์ด์ ๋ฒ์ ์ ๋์ด์ง ์๊ณ ๊ทธ๋ฌํ ์ผ์ ํ ๋.์ถ์ : ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ๊ป ํ๋ ๋ชจ๋ ํ๋ฅญํ ์์ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค ๐
โ
๋น์ ์ด ๋๊ธ์ ๋ฌ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/caolan/async/issues/1386#issuecomment-291875817 ๋๋ ์์๊ฑฐ
์ค๋ ๋
https://github.com/notifications/unsubscribe-auth/ADUIEPNkTSOVuuiwucBVrH983X6B568Wks5rs6K3gaJpZM4Mf64R
.
๋์ํฉ๋๋ค, ๊ทธ๊ฒ์ ๋ด ๋น๋๋ ๋ง์ณค์ต๋๋ค ...
๋ฉฐ์น ์ ์ ์๋ํ๋ ๋น๋๊ธฐ ํจ์๋ฅผ ํธ์ถํ๋ ํญํฌ์๋ ๋น๋๊ธฐ ์ฝ๋ฐฑ์ด ๋ ์ด์ ํจ์์ ์ ๊ณต๋์ง ์์๊ธฐ ๋๋ฌธ์ "cb is not function"๊ณผ ํจ๊ป ์คํจํ๊ธฐ ์์ํ์ต๋๋ค.
์ฃ์กํฉ๋๋ค. ์ฝ๋๊ฐ ์์๋์์ต๋๋ค. async
๊ธฐ๋ฅ์ ๋ํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์์ํ์ง ๋ชปํ์ต๋๋ค. ์ฝ๋ฐฑ์ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค 2.2.0์ผ๋ก ๋กค๋ฐฑํ๊ฑฐ๋ ์ฝ๋๋ฅผ ํ์ํ ๊ฐ์ผ๋ก return
๋ฆฌํฉํ ๋งํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ถํํ๋ ๊ณ ์์ด๋ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ๋กค๋ฐฑํ ์ ์์ต๋๋ค.
@aearly ์ ๋ฐ, ์ธ๊ธํ์ง ๋ง์ธ์!! ๋ต๋ณํด์ฃผ์ ์ ์ ๋ง ๊ฐ์ฌํฉ๋๋ค :1st_place_medal:
@manvalls ๋ ๋กค๋ฐฑ์ด ํ์ํ์ง ์์ ํ๋ฅญํ ์๋ฃจ์
์ ์์ํ์ต๋๋ค. ํจ์ ์ ์ธ์์ async
๋ฅผ ๊ฐ์งํ๊ธฐ ์ํด ๊ธฐํธ๋ฅผ ์ฌ์ฉํ๋ฉด์ ๊ทธ๋ ๊ฐ์ง๋ฅผ ์์ผ ์ ์๋ ์๋ฆฌํ ๋ฐฉ๋ฒ์ ์๊ฐํ์ต๋๋ค.
๋ด ํญํฌ์๋ ๋ค๋ฅธ ๋ชจ๋์์ ๋ด๋ณด๋ธ ํจ์๋ฅผ ์ฌ์ฉํ๊ณ ์์๋๋ฐ ๊ทธ ์ค ํ๋๊ฐ async
์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
๋ฐ๋ผ์ ๋ค์์์ ๋ณ๊ฒฝํ๋ฉด ๋ฉ๋๋ค.
...
/* services module */
function doThis(param, cb) {
...
}
async function doThatAsync(param, cb) {
...
}
module.exports = {
doThis: doThis,
doThat: doThatAsync
};
...
async.waterfall([
services.doThis,
services.doThat, // fails with "cb is not a function"
], err => {
...
}
์๊ฒ:
...
/* services module */
function doThis(param, cb) {
...
}
async function doThatAsync(param, cb) {
...
}
module.exports = {
doThis: doThis,
doThat: (...args) => doThatAsync(..args) // cheating the detection
};
...
async.waterfall([
services.doThis,
services.doThat, /* it works!!! */
], err => {
...
}
๋ค์ํ๋ฒ ์ง์ฌ์ผ๋ก ๊ฐ์ฌ๋๋ฆฝ๋๋ค
async.autoInject()์ ํจ๊ป async/await๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๊น?
async.autoInject({
conn1: async function () {
return conn1;
},
conn2: async function () {
return conn2;
},
});
์๋ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ค๋ฅ: autoInject ์์ ํจ์์๋ ๋ช ์์ ๋งค๊ฐ๋ณ์๊ฐ ํ์ํฉ๋๋ค.
/Users/alexamil/WebstormProjects/nabisco/cdt-now/node_modules/async/dist/async.js:2081:23์์
/Users/alexamil/WebstormProjects/nabisco/cdt-now/node_modules/async์์
@ORESoftware ์, async
ํจ์๋ autoInject
์ ํจ๊ป ์๋ํด์ผ ํฉ๋๋ค. Chrome์ ๊ฒ์ํ ์ฝ๋๋ฅผ ํ
์คํธํ๋๋ฐ ์คํ๋์์ต๋๋ค. conn1
๋ฐ conn2
๊ฐ undefined
์ด๋ฏ๋ก ์ต์ข
์ฝ๋ฐฑ์์ ReferenceError
๋ฅผ ๋ฐ์์ต๋๋ค. ๋ก ๋ณ๊ฒฝํ ํ
async.autoInject({
conn1: async function () {
return 'foo'
},
conn2: async function () {
return 'bar'
},
})
์ ์๋ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ํธ๋์คํ์ผ๋ async
ํจ์๋ฅผ ์ง์ํ์ง ์์ต๋๋ค. ์ฝ๋๋ฅผ ํธ๋์คํ์ผํ๊ณ ์์ต๋๊น?
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๊ทธ๊ฒ์ด ๋ฐ๋ก ํ์ค ECMA ์ฌ์ ๋ฐฉ์์ ๋๋ค. ์ด๋ก ์ ์ผ๋ก ๋๊ตฐ๊ฐ
asyncFn[Symbol.toStringTag]
๋ฅผ ๋ฎ์ด์ธ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.๋๋ ๋น์ ์ด ๊ทธ๊ฒ์ ์ฝ๊ฐ ๋ค๋ก ๊ฐ์ง๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฝ๋ฐฑ์ ํ์ฉํ๋ ๋ฐ๋ณต ํจ์(
function(args..., callback) {}
)๋ฅผ ์๋ฝํ ๋๋ง๋คasync
ํจ์์ธ์ง ํ์ธํ ๋ค์asyncify
$ ํจ์์ธ์ง ํ์ธํด์ผ ํฉ๋๋ค.await
์์ ๋ Async ๋ฉ์๋๋ฅผawait
๋ก ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ ์ํํ ์์ ์ ๋๋ค. Async ๋ฉ์๋๊ฐ ์ฝ์์ ๋ฐํํ๊ธฐ ์์ํ๋๋ก ํด์๋ ์ ๋๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋์ผ ์๋ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ํ๋๋ก ๋๋์ญ์์ค.