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
将不可用
随着希望清除,这是我认为你想要重写你的代码:
我认为你需要的一些改变是:
-
你实际上并不需要函数
readFile
,你可以直接使用fs.readFileAsync
。 -
来自
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