node js async λͺ¨λ μ¬μ©νκΈ°
Node λ κΈ°λ³Έμ μΌλ‘ λΉλκΈ°μμΌλ‘ μλμ ν©λλ€. μ¦ 1 2 3 4 5 μμλ‘ μ½λ©μ νμ΄λ λ°λμ 1 2 3 4 5 μ μμλ‘ μ€νμ νμ§ μλ λ€λ μκΈ°μ λλ€. μλ²μͺ½μμλ λΉλκΈ°μμΌλ‘ μλνλ κ²μ΄ λ ν¨μ¨μ μΈ μν©μ΄ λ§μ§λ§ λ°λμ μμ°¨μ μΌλ‘ μλν΄μΌν νλ‘μΈμ€λ μκΈ° λ§λ ¨μ λλ€. μ κ° μμ νλ κ³Όμ μ€ κ·Έλ¬ν κ³Όμ μ΄ μμ΄μ asyncλΌλ λͺ¨λμμ waterfallμ μ¬μ©ν κ²½ν λ° μ½λλ₯Ό μ¨λ³΄κ³ μ ν©λλ€. μΌλ¨ μ κ³Όμ μ μ΄λ μ΅λλ€.
μΉ μμμ μ»΄νμΌμ΄ κ°λ₯ν μλν°λ₯Ό ꡬννμλλ° κ³Όμ μ 보μλ©΄ μμκ² μ§λ§ μμ±λμ§λ μμ νμΌμ μ»΄νμΌ ν μλ μμ κ²μ΄κ³ μ»΄νμΌμ΄ μλ νμΌμ μ€ννλ κ²λ λΉμ°ν λΆκ°λ₯ ν κ²μ λλ€. κ·Έλμ μμ κ°μ κ³Όμ μ λκΈ°μ μΌλ‘ μ΄λ£¨μ΄μ ΈμΌνλ κ³Όμ μ΄κΈ° λλ¬Έμ κ·Έλ₯ μμ°¨μ μΈ μ½λ νΉμ ν¨μ ννλ‘ μ§λ©΄ μλκ³ μ½λ°±νμμ μ΄μ©νλ λκΈ°μ μΈ ννλ‘ μμ±ν΄μΌ νμ΅λλ€.
μ 체μ μΈ μ½λμ λλ€.
let fs = require('fs'); let spawn = require('child_process').spawn; let cp = require('child_process'); let exec = require('child_process').exec; let models = require('../models'); let async = require('async'); function compileFunction(lan,path,source,res){ let file, compile,run,responseData; let tasks = [ //νμΌ μμ± function(callback){ if(lan==='c') file = path+'test.c'; else if(lan==='java') file = path+'Test.java'; else if(lan==='python') file = path+'test.py'; fs.writeFile(file,source,'utf-8',err=>{if(err) throw err;}); callback(null,file); }, //μμ±λ νμΌμ μ»΄νμΌ function(file,callback){ if(lan==='c'){ compile = exec('gcc test.c',{cwd:'sources'},(err,stdout,stderr)=>{ if(stderr.length===0){ let run = spawn('./sources/./a.out',[]); run.stdout.on('data',stdout=>{ callback(null,stdout.toString('utf8')); }) } else callback(true,stderr) }) } else if(lan==='java'){ compile = exec('javac Test.java',{cwd:'sources'},(err,stdout,stderr)=>{ if(stderr.length===0) { let run = exec("java Test",{cwd:'sources'},(err,stdout,stderr)=>{ callback(null,stdout); }); } else callback(true,stderr) }) } else if(lan==='python'){ compile = exec('python3 test.py',{cwd:'sources'},(err,stdout,stderr)=>{ if(stderr.length===0) { callback(null,stdout) } else callback(true,stderr) }) } }, //μ»΄νμΌ ν λμ¨ κ²°κ³Όλ₯Ό λ°ν function(stdout,callback){ callback(null,stdout) } ] async.waterfall(tasks,(err,msg)=>{ if(err){ responseData = {'result':'err','output':msg}; res.json(responseData); } else{ responseData = {'result':'ok','output':msg}; res.json(responseData); console.log('done'); } }); } exports.compileFunction = compileFunction;
μ λλ‘ μ€νλλ κ²λ§ νμΈνκ³ μμ§ λ€λ¬μ§λ μμ μνμ¬μ μ½λκ° μ§μ λΆν μνμ λλ€. waterfallμ΄λΌλκ² λ§ κ·Έλλ‘ νν¬μμ ννλ₯Ό λλ€κ³ ν΄μ λΆμ¬μ§ μ΄λ¦μΈλ° functionμ΄ λ§μΉ νν¬μμ²λΌ λμ΄λλ©°, μ λ¨κ³ ν¨μμ κ²°κ³Όλ₯Ό λ€μ λ¨κ³μ λ³μκ°μΌλ‘ μ¬μ© κ°λ₯ν callback ννλ₯Ό λκ³ μμ΅λλ€. μ¬μ©μ λͺ¨λννλ‘ μ°κΈ°μν΄μ λ°λ‘ λΆλ¦¬μμΌ λμ js νμΌμ΄κΈ°λλ¬Έμ λ§€κ°λ³μλ μ΄λ―Έ app.js νμΌμμ λμ΄μ¨ μνμΈλ° κ·Έλ°κ±΄ μ μ³λκ³ λμ κ³Όμ λ§ μ€λͺ ν΄λ³΄κ² μ΅λλ€.
let tasks = [ //νμΌ μμ± function(callback){ if(lan==='c') file = path+'test.c'; else if(lan==='java') file = path+'Test.java'; else if(lan==='python') file = path+'test.py'; fs.writeFile(file,source,'utf-8',err=>{if(err) throw err;}); callback(null,file); }, //μμ±λ νμΌμ μ»΄νμΌ function(file,callback){ if(lan==='c'){ compile = exec('gcc test.c',{cwd:'sources'},(err,stdout,stderr)=>{ if(stderr.length===0){ let run = spawn('./sources/./a.out',[]); run.stdout.on('data',stdout=>{ callback(null,stdout.toString('utf8')); }) } else callback(true,stderr) }) } else if(lan==='java'){ compile = exec('javac Test.java',{cwd:'sources'},(err,stdout,stderr)=>{ if(stderr.length===0) { let run = exec("java Test",{cwd:'sources'},(err,stdout,stderr)=>{ callback(null,stdout); }); } else callback(true,stderr) }) } else if(lan==='python'){ compile = exec('python3 test.py',{cwd:'sources'},(err,stdout,stderr)=>{ if(stderr.length===0) { callback(null,stdout) } else callback(true,stderr) }) } }, //μ»΄νμΌ ν λμ¨ κ²°κ³Όλ₯Ό λ°ν function(stdout,callback){ callback(null,stdout) } ]
=> λκΈ°μ μΌλ‘ μλν΄μΌν functionλ€μ λ°°μ΄ννλ‘ μμ±ν΄μ€ κ²μ λλ€. μκΉ μμμλ νλ¦λλ₯Ό 첨λΆνμλλ° κ±°κΈ°μ μ½κ°μ μ€λͺ μ λν΄λ³΄κ² μ΅λλ€.
μ λΉ¨κ°μ μꡬμ¬νλ€μ΄ callback ν¨μμ λ§€κ°λ³μλ‘ λ€μ΄κ° κ°λ€μ λλ€. νμΌμ μ λ¬ν΄μ€μΌ μ»΄νμΌμ ν ν κ³ μ€ννμΌμ΄ μμ΄μΌ μ€νμ νκ² μ£ κ΅μ₯ν λ¨μν μ΄μΉμ λλ€. νμ ν¨μμ λμ callback(null, μ λ¬ν λ³μ) μ ννλ‘ νΈμΆμ νλ κ²μ λ³Ό μ μμ΅λλ€. κ·Όλ° nullμ λλ체 μ λ€μ΄κ°λκ±΄κ° κΆκΈν΄μ μ λ μ°Ύμ λ΄€μ΅λλ€.
κ΅¬κΈ λ²μκΈ°μ λμμΌλ‘ λ²μμ ν΄λ³΄λ
--------------------google λ²μ-------------------------
μΌλ°μ μΌλ‘ λ Έλμμ μ½λ°±μ 첫 λ²μ§Έ μΈμλ μΌλ°μ μΌλ‘ μ€λ₯λ₯Ό λνλ΄λ λ° μ¬μ©λ©λλ€. κ·Έκ²μ΄ nullμ΄ μλ λ€λ₯Έ κ²μ΄λΌλ©΄, μ΄λ€ μ΄μ λ‘ λ μμ μ΄ μ€ν¨νμ΅λλ€. μλ§λ νΈμΆ μμ μκ° λ³΅κ΅¬ ν μ μμ§λ§ νΈμΆμκ° λ³΅κ΅¬ ν μμλ κ²μΌ μ μμ΅λλ€. 첫 λ²μ§Έ μΈμ μ΄νμ λ€λ₯Έ μΈμλ μ°μ°μ λ°ν κ°μΌλ‘ μ¬μ©λ©λλ€ (μ±κ³΅ν λ©μμ§, κ²μ λ±).
---------------------------------------------------------
λΌκ³ ν΄μμ΄ λμ΅λλ€. λΆμκΈ°μ λ§μΉ κ΄μ΅μ μΌλ‘ κ·Έλ κ² μ°μΈλ€ λΌλ λμμ€λ₯Ό 보μ΄λκ±Έ 보λ λ€λ₯Έ μΈμ΄μμλ μλ μλ μκ² μ§λ§ nodeμμλ κ΄μ΅μ μΌλ‘ κ·Έλ κ² μ°λλ³΄λ€ νκ³ μΌλ¨ λμ΄κ°κ² μ΅λλ€. μ¦ μ°λ¦¬κ° μ κ²½μ¨μΌν μΈμλ 첫 λ²μ§Έ μΈμ μ΄νλΌλ κ²μ
λλ€.
μλ¬΄νΌ λ°°μ΄ννλ‘ μ¬λ¬κ°μ ν¨μλ₯Ό λͺ¨λ μμ±νλ€ μΉλ©΄ λκΈ°μμΌλ‘ μλμν€λ λ°©λ²μ κ°λ¨ν©λλ€.
async.waterfall(tasks,(err,msg)=>{ if(err){ responseData = {'result':'err','output':msg}; res.json(responseData); } else{ responseData = {'result':'ok','output':msg}; res.json(responseData); console.log('done'); } });
asyncμ waterfallμ μ΄μ©νμ¬ λ§€κ°λ³μλ‘ μμ±ν ν¨μμ λ°°μ΄κ³Ό μ½λ°±ν¨μλ₯Ό μ΄μ©νμ¬ μ λλ‘ μ€νμ΄ λλμ§ νμΈν μ μμ΅λλ€. μλλ©΄ κ° ν¨μμ λ¨κ³λ§λ€ logλ₯Ό μ°μ΄μ λ΄κ° μκ°ν μμλλ‘ μ€νλκ³ μλμ§ νμΈνμ λ λ©λλ€.