javascript - Promise code are read twice -
i use following code read json file , return promise i've 2 questions
return globasync("folder/*.json").catch(function (err) { throw new error("error read: " + err); }).map(function (file) { return fs.readfileasync(file, 'utf8') .then(function (res) { console.log("test"); return json.parse(res); }, function (err) { throw new error("error :" + err); }).then(function () { console.log("test2"); }); });
i use console log , see console printed twice
test test test2 test2
why happening , how avoid ?
- in place i've put
console.log("test2");
need invoke event json parse finished , still return outside json object (to caller), when add lastthen
doesn't work(the returned object undefined),any idea how right?
update try following doesn't work...
return globasync("folder/*.json").catch(function (err) { throw new error("error read: " + err); }).map(function (file) { return fs.readfileasync(file, 'utf8') .then(function (res) { console.log("test"); json.parse(res); //data parse }.catch(function (err) { throw new error("error :" + err); } ).then(function (data) { obj.emit('ready'); return data; })) }); }
update2 able solve add new return json.parse(res);
how should solve first issue method called twice
like @jaromandax said, got 2 *.json
files. try print out file name instead , should become more obvious. in case, .map
expected called twice, once each file. otherwise aren't gonna able read , parse 2 files together.
if want converge single point after file reads , parses complete, need chain .then
after .map
. eg.
return globasync("folder/*.json") .map(function(file) { ... }) .then(function() { obj.emit('ready'); });
edit answer question in comment. there few things should keep in mind.
- throwing error inside promise chain caught promise , send rejection flow. may still throw error if interested in getting custom error type or printing stack trace in desirable way. people prefer
return promise.reject(error)
. - any rejection in
.map
send promise chain rejection flow. - inside rejection chain, if want continue down rejection flow. need
return promise.reject(error)
, otherwise if don't return reject object, can bring resolve flow.
if want want handle each error individually, can this:
return globasync("folder/*.json") .catch(function(error) { // todo: handle error return promise.reject(error); }) .map(function(file) { return fs.readfileasync(file, 'utf8') .catch(function(error) { // todo: handle error return promise.reject(error); }) .then(function(res) { return json.parse(res); }); }) .then(function() { obj.emit('ready'); });
if want handle once glob , once file read, have bit more creative.
return globasync("folder/*.json") .catch(function(error) { // todo: handle error return promise.reject(error); }) .then(function(files) { return promise.resolve(files) .map(function(file) { return fs.readfileasync(file, 'utf8'); }) .catch(function(error) { // todo: handle error once read error return promise.reject(error); }) .map(function(res) { // judging original code, not handling // parser error, wrote code behave equivalent // original. otherwise chain parse immediate after // readfileasync. return json.parse(res); }); }) .then(function() { obj.emit('ready'); });
Comments
Post a Comment