2016-12-06 25 views
0

我有一個Node.Js Web應用程序與Express.Js從xml文件中讀取值,將所有xml文件中的值存儲到一個數組與子數組代表每隔xml文件。此刻,我對節點下面的代碼: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); 
    }); 
}); 
} 

到目前爲止,對於 「執行console.log(all_software_requests);」主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)); 

我惹諾/回調風格這裏來縮小你的代碼版本。
更好地在客戶端代碼中使用承諾而不是回調。

然後它就像變成:

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

嗨,我添加簡單的解決方案,沒有'承諾' –

+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

你好,謝謝你的回答。這引入了一個很少提及的新概念。請問另外一個問題:接下來添加函數後,「xmldata.ProjectRequest」變得未定義。其次功能不需要任何參數? –

相關問題