2017-11-04 5 views
0

ich hier asynchronen Code promises.The Problem zu laufen versuchen ist, dass die Antwort auch genannt wird, bevor die Rückrufe ihre Ausführung beenden.Versprechen nicht in Knoten JS arbeiten

Anmerkung: Ich schrieb eine Callback-Funktion in einem loop.I ein Array drucken, nachdem die Schleife das Array finished.But wird gedruckt wird, bevor die Schleife endet.

My question is : 
1) Is it correct to use a callback within a loop? 
2)If not,then what are the other methods of repeating a callback function. 

Der Code lautet wie folgt:

router.post('/run',function(req,res){ 


    var code=req.body.code; 
    var lang=req.body.lang; 
    var input=req.body.input; 
    var result=[]; 
    switch(lang){ 
     case 1: 
    calculate(code,input).then(function(res){ 
       console.log(res); 
     }); 
    } 
}); 



function calculate(code,input){ 
    var result=[] 
return new Promise((resolve,reject)=>{ 
    for(let i=0;i<input.length;i++){ 

    compile_run.runPython(code, input[i], function (stdout, stderr, err) { 
     if(!err){ 
       console.log(stdout); 
       result.push(stdout); 
     } 
     else{ 
      console.log(err); 

     } 


    }); 
    } 
    resolve(result); 
}) 
} 

Wie gesagt, die Anweisung console.log (res) in der Case-Anweisung druckt '[]'.

Bitte helfen!

Vielen Dank im Voraus!

+0

Was ist _compile_run.runPython_? – TGrif

+0

Es ist ein Modul zum Kompilieren des angegebenen Codes in einer bestimmten Sprache mit der angegebenen Eingabe. (Sowohl der Code als auch die Eingabe werden vom Front-End empfangen.) – Raman

+0

Sie lösen das Ergebnis _before_ die Kompilierung ist abgeschlossen. – TGrif

Antwort

1

compile_run.runPython() ist ein Asynchron-Betrieb und Sie Schleifen über und es mehrmals aufrufen. Dies bedeutet, Sie müssen warten können, bis jeweils endet. Das Umschließen der gesamten Schleife in einem Versprechen funktioniert nicht (wie Sie gesehen haben), da Sie das Versprechen lösen, bevor alle einzelnen asynchronen Vorgänge zurückgegeben wurden.

Damit dies funktioniert, müssen Sie ein Versprechen für jeder async Operation erstellen. Promise.all() kann hier helfen, indem es eine Reihe von Versprechen einnimmt und alle zurückbringt, sobald alle fertig sind.

Ich bin nicht vertraut mit compile_run so habe ich das nicht laufen, aber es sollte Ihnen einen guten Ausgangspunkt geben:

function calculate(code,input){ 
    var promiseArray = input.map(inp => { 
     return new Promise((resolve, reject) => { 
      compile_run.runPython(code, inp, function (stdout, stderr, err) { 
       if(!err){ 
        console.log(stdout); 
        resolve(stdout); 
       } 
       else{ 
        reject(err) 
       } 
      }) 
     }) 
    }) 
    return Promise.all(promiseArray) 
} 

promiseArray wird eine Reihe von Versprechen sein - eine für jedes Mal durch die Schleife. Promise.all wird aufgelöst, sobald alle mit einem Array abgeschlossen sind, das alle Ergebnisse enthält. Sie sollten dann in der Lage sein zu verwenden:

calculate(code,input) 
.then(result => { 
    // use results here 
}) 
.catch(err => console.log(err)) 
+0

Sie sind fantastisch! Vielen Dank. Das hat mein Problem gelöst. Danke für die klare und vollständige Erklärung – Raman

Verwandte Themen