簡體   English   中英

node.js承諾錯誤的底層函數

[英]node.js promises error underfined function

我的問題是解析大型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.readFileSyncfs.readFileAsync 前者是fs的內置函數,它直接返回數據。 后者是由Bluebird promisification 創建的 函數它返回一個promise。

以下是他們使用方式的不同之處:

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);
});

注意實際創建fs.readFileSyncAsync所需的require('bluebird')Promise.promisifyAll(fs) ,否則fs將無法在fs

有希望清除,這就是我認為你想重寫代碼的方式:

我認為你需要的一些改變是:

  1. 你實際上並不需要函數readFile ,你可以直接使用fs.readFileAsync

  2. parseString它來源於require('xml2js')會更好,如果你只是promisified xml2js自己喜歡fs和使用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返回結束值(字符串或緩沖區)。 它是同步的。 您的代碼中沒有任何承諾,因此您會收到TypeError

readFileSync不返回promise,使用它的方式是

value = readFileSync(filename,options);

value將是字符串或緩沖區,具體取決於編碼選項

請參閱https://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_options

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM