node.js承诺错误的定义函数

我的问题是parsing大xml文件(与xml2js),forEach元素在周期(产品),下载图像,并将其保存到文件。 我写了这个代码:

var fs = require('fs'); var request = require('request'); var parseString = require('xml2js').parseString; var baseUrl = 'http://shop.nag.ru/uploads/catalog_item_image_main/'; var async = require('async'); var processImg = require('./downloader'); var q = require('q'); var readFileSync = function (){ var xml = fs.readFileSync("./test.xml", "utf8"); return xml; }; readFileSync.then(function(xml) { parseString(xml, function (err, result) { if(err)return error; return result.product_list.product; }) }) .then(function(products){ products.forEach(function(prdt) { }); }).catch(function (err) { console.log(err); }); 

但运行后,我得到这个错误:

 readFileSync.then(function(xml) { ^ TypeError: undefined is not a function at Object.<anonymous> (D:\WorkVrp\nodeImageParser\processing.js:19:14) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Function.Module.runMain (module.js:501:10) at startup (node.js:129:16) at node.js:814:3 

我认为你错误fs.readFileSync fs.readFileAsync 。 前者是直接返回数据的fs的内置函数。 后者是由Bluebird promisification 创造的 函数 ,它返回一个承诺。

以下是他们将被使用的不同方式:

fs.readFileSync

 var fs = require('fs'); try { var data = fs.readFileSync('./file.xml', 'utf8'); // do something with data } catch(err) { console.error(err); } 

fs.readFileAsync

 var fs = require('fs'); var Promise = require('bluebird'); Promise.promisifyAll(fs); fs.readFileSyncAsync('./file.xml', 'utf8') .then(function(data){ //do something with data }) .catch(function(err){ console.error(err); }); 

注意require('bluebird')Promise.promisifyAll(fs) ,它们是实际创buildfs.readFileSyncAsync所必需的,否则fs.readFileSyncAsync将不可用

随着希望清除,这是我认为你想要重写你的代码:

我认为你需要的一些改变是:

  1. 你实际上并不需要函数readFile ,你可以直接使用fs.readFileAsync

  2. 来自require('xml2js') parseString会更好,如果你只是将xml2js自身像fs一样进行了xml2js并且使用了xml2js.parseStringAsync

我也走在前面,拿出你之前提出的问题的代码,这大概会对你更全面的了解:

 var fs = require('fs'); var request = require('request'); var xml2js = require('xml2js'); var Promise = require('bluebird'); Promise.promisifyAll(fs); Promise.promisifyAll(request); Promise.promisifyAll(xml2js); var baseUrl = 'http://test.com/uploads/catalog_item_image_main/'; var processImg = require('./downloader'); var processImgAsync = Promise.promisify(processImg); fs.readFileAsync("./test.xml", "utf8") .then(xml2js.parseStringAsync) .then(parseProductsAsync) // defined below .then(processProductsAsync) .then(function(){ console.log('All prdt have been processed successfully'); }) .catch(console.error); function parseProductsAsync(xmljsonresult){ return xmljsonresult.product_list.product; } function processProductsAsync(products){ return Promise.all(products.map(function(product){ console.log('Processing file ' + product.sku); var filename = product.sku + ""; filename = filename.replace(/\//g, '_'); return processImgAsync(baseUrl + filename + '_big.', filename); })); } 

fs.readFileSync返回一个结束值(string或缓冲区)。 它同步。 你的代码没有承诺,所以你得到TypeError

readFileSync不返回一个承诺,使用它的方式是

value = readFileSync(filename,options);

值将是一个string或缓冲区,取决于编码选项

请参阅https://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_options