2016-12-06 19 views
0

xmlファイルから値を読み取り、すべてのxmlファイルの値をサブ配列の配列に格納するExpress.Jsを持つNode.Js Webアプリケーションが、 xmlファイル。 "にconsole.log(all_software_requests);" のために、これまでのところJavaScriptコールバックは、値がループ内にプッシュされた配列です

app.get('/get_software_requests', function (req, res) { 
console.log("loading software requests"); 
requests_callback(function(all_software_requests){ 
    console.log(all_software_requests); 
}); 

function requests_callback(callback){ 
    loadAllSoftwareRequests(function(all_software_requests){ 
    callback(all_software_requests); 
    }); 
} 
}); 

function loadAllSoftwareRequests(callback){ 
console.log("loading requests"); 
fs.readdir("/project_requests", function(error, files) { 
    files.forEach(filename => { 
     var software_request = new Array(); 
     loadSoftwareRequestXML(filename, software_request, function(software_request){ 
      all_software_requests.push(software_request); 
      callback(all_software_requests); 
     }); 
    }); 
}); 
} 

function loadSoftwareRequestXML(filename, software_request, callback){ 
var xmlparser = new xml2js.Parser(); 
var filepath = "/project_requests/" + filename; 
fs.readFile(filepath, "utf-8", function(error, values){ 
    xmlparser.parseString(values, function(error, xmlfile){ 
     var xmldata = xmlfile; 
     date_requested = xmldata.ProjectRequest.DateRequested; 
     client_org = xmldata.ProjectRequest.ClientOrganization; 
     proposed_budget = xmldata.ProjectRequest.ProposedBudget; 
     contact_name = xmldata.ProjectRequest.ContactName; 
     delivery_date = xmldata.ProjectRequest.DeliveryDate; 
     requirements = xmldata.ProjectRequest.UserRequirements; 
     software_request.push(date_requested); 
     software_request.push(client_org); 
     callback(software_request); 
    }); 
}); 
} 

:現時点では、私は、ノード上で次のコードを持っていますメインapp.get、コンソール出力に:

enter image description here

私は唯一のノードは高く評価され

enter image description here

すべてのヘルプや提案のように、最後の反復の結果を返したいです。お気軽にコメントしてください。ありがとう。

答えて

0

あなたはそのためにネイティブの約束を使用することができます。

Promise.all(files.map(
    filename => new Promise(ok => load(filename, request => ok(request))) 
)).then(requests => callback(requests)); 

I混乱を約束/コールバックスタイルでここにコードエディションを縮小化します。
クライアントコードでもコールバックの代わりに約束を使用する方が良い。

そして、それだけで次のようになります。それはあまりにも難しいことではありませんすべての約束がなければ

let loadAll = files => Promise.all(files.map(load)); 
let load = filename => {/*return some promise with result*/} 

let c = files.length; // initialize a counter 
files.forEach(filename => { 
    var software_request = new Array(); 
    loadSoftwareRequestXML(filename, software_request, function(software_request){ 
     all_software_requests.push(software_request); 
     if(!--c) { // all async calls are finished 
      callback(all_software_requests); 
     } 
    }); 
}); 
+0

こんにちは、お寄せいただきありがとうございます。 –

+0

こんにちは、私は 'Promise'なしで簡単なソリューションを追加します –

+0

シンプルなソリューションをありがとう。それは美しく働いた! :) –

0

あなたはまた、あなたのためのループを処理する私の「次」メソッドを追加することができます。これは、これらのタイプの状況で私にとってうまくいきました。

app.get('/get_software_requests', function (req, res) { 
    console.log("loading software requests"); 
    requests_callback(function(all_software_requests){ 
     console.log(all_software_requests); 
    }); 

function requests_callback(callback){ 
    loadAllSoftwareRequests(function(all_software_requests){ 
    callback(all_software_requests); 
    }); 
    } 
}); 

function loadAllSoftwareRequests(callback){ 
console.log("loading requests"); 
fs.readdir("/project_requests", function(error, files) { 
    files.forEach(filename => { 
     var software_request = new Array(); 
     loadSoftwareRequestXML(filename, software_request, function(software_request){ 
      all_software_requests.push(software_request); 
      callback(all_software_requests); 
     }); 
    }); 
}); 
} 

function loadSoftwareRequestXML(filename, software_request, callback){ 
var xmlparser = new xml2js.Parser(); 
var filepath = "/project_requests/" + filename; 
fs.readFile(filepath, "utf-8", function(error, values){ 
    var index = 0; 
    var next = function() { 
    if (index >= values.length) { 
     callback(null, values); 
     return; 
    } 
    var value = values[index]; 
    xmlparser.parseString(value, function(error, xmlfile){ 
     var xmldata = xmlfile; 
     date_requested = xmldata.ProjectRequest.DateRequested; 
     client_org = xmldata.ProjectRequest.ClientOrganization; 
     proposed_budget = xmldata.ProjectRequest.ProposedBudget; 
     contact_name = xmldata.ProjectRequest.ContactName; 
     delivery_date = xmldata.ProjectRequest.DeliveryDate; 
     requirements = xmldata.ProjectRequest.UserRequirements; 
     software_request.push(date_requested); 
     software_request.push(client_org); 
     value.software_request = software_request; 
     index++; 
     next() 
    }); 
    } 
    next(); 
}); 
} 
+0

こんにちは、あなたの答えをありがとう。これはめったに言及されていない新しい概念を導入しました。もう1つ質問してください。次の関数を追加した後、 "xmldata.ProjectRequest"が未定義になりました。次に機能しないパラメータが必要ですか? –

関連する問題