我对编码和Node.JS很新,但是我试图学习......我发现Node.JS的第一个重大困难是在构建代码时以异步方式思考,现在我正面临另一个怪物:承诺。
到目前为止,我已经尝试构建我的代码以获得一些工作而不关心所有的错误处理(我知道这很愚蠢,但它有助于我学习)但是现在在运行我的代码时出现了一些错误不时。
由于“my program”基本上(现在)通过无限循环进行一堆请求(使用request-promise)。对收到的信息({objects}
)的一些操纵并将其发送到mongodb(通过mongoose),我大多知道错误的来源:
statusCode !== 200
)。statusCode
)我的代码运行得非常顺利,直到我收到其中一个错误。我的目标是回到代码中以正确处理这些错误并在日志发生后创建它们。另一个理想的功能是重新启动发生错误(请求)的loop
(可能在setTimeout
或之后)。
我的问题是:
promiseRejection
处理的优质材料?现在我为每个承诺使用.catch((err) => { foo })
,但是我不知道一旦被捕,我该怎么处理错误。 promiseRejection
处理(可能是npm包)的内容?loop
重启?再说一次,我并不期望你能够对整个代码提供完整的响应(如果你能做到这一点显然更好),而是让我朝着正确的方向(最佳实践,着名的npms或文章来实现这一目标)! 我真的希望我不会脱离主题并遵循SO的规则!如果没有让我知道,我将删除该问题或编辑和改编。 在此先感谢您的帮助!
*******编辑********
简化我的代码:
[] ./模块/ apiRequest.js []
var rq = require('request-promise');
var fs = require('fs');
function apiRequest(params, req) {
var date = new Date().toISOString();
var logFileName = '../logs/[KRAKEN]'+date+'errorlog.txt';
var options = {
uri: `https://api.kraken.com/0/public/${params}`,
qs: req,
json: true,
resolveWithFullResponse: true
};
return rq(options).then((res) => {
if (res.statusCode === 200 && !res.body.error.length) {
return res; // <=== THIS FOR AN UNKNOWN PARAM, THIS SERVER RETURNS A 200 WITH AN ERROR OBJECT.
} else {
fs.writeFile(logFileName, res, function(err) {
if (err) return console.log(err); // <==== SINCE A 200 WON'T APPEAR AS AN ERROR I'M TRYING TO HANDLE IT THAT WAY.
console.log(`[ERROR][KRAKEN]: log created!`);
});
}
}).catch((err) => { // <==== AS FAR AS I UNDERSTAND THIS IS FOR ANY OTHER ERROR (STATUSCODE 500 FOR INSTANCE / OR AN ERROR RELATED WITH THE CODE)
fs.writeFile(logFileName, err, function(err) {
if (err) return console.log(err);
console.log(`[ERROR][KRAKEN]: log created!`);
});
});
};
module.exports = {
apiRequest
};
[] ./模块/ app.js []
var apiRequest = require('./apiRequest.js').apiRequest;
function kraken(item) {
return apiRequest('Ticker', {pair: item}).then((res) => {
var result = {};
var timeStamp = Math.floor(new Date());
Object.keys(res.body.result).forEach((k) => {
result= {
mk: 'kraken',
name: k,
a: res.body.result[k].a,
b: res.body.result[k].b,
c: res.body.result[k].c,
v: res.body.result[k].v,
p: res.body.result[k].p,
t: res.body.result[k].t,
l: res.body.result[k].l,
h: res.body.result[k].h,
o: res.body.result[k].o,
n: timeStamp,
}
});
return result; // <=== THIS OCCURS WHEN THERE'S NO ERROR IN THE APIREQUEST.
}).catch((err) => {
console.log(err); // <==== THIS I'M NOT SURE IF IT GETS THE ERROR BACK FROM APIREQUEST. IF I'M NOT MISTAKEN THAT'S NOT THE CASE, IT'S THE ERROR HANDLER FOR THE 'kraken' FUNCTION I'M NOT SURE WHAT KIND OF ERRORS COULD COME OUT OF THIS...
});
};
module.exports = {
kraken,
}
[] ./ main.js []
var fs = require('fs');
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
// KRAKEN REQUIRE:
var kraken = require('./module/app.js').kraken;
var Krakentick = require('./module/model/krakenModel').Krakentick; //<=== THIS IS THE MODEL FOR MONGOOSE.
async function loopKR() {
setTimeout(
async function () {
var item = ['XBTUSD'];
var data = await kraken(item);
data.forEach((object) => {
if (object.name === 'XXBTZUSD') {
var iname = 'btcusd'
} else {
var iname = 'N/A' };
var tick = new Krakentick({
mk: object.mk,
name: object.name,
a: object.a,
b: object.b,
c: object.c,
v: object.v,
p: object.p,
t: object.t,
l: object.l,
h: object.h,
o: object.o,
n: object.n,
iname: iname,
});
tick.save(function(err, tick) {
if (err) return console.log(err); //<==== THIS IS RELATED WITH MONGOOSE NOT A PROMISE IF I'M NOT MISTAKEN... THEN HANDLING WOULD OCCUR IF I HAD A PROBLEM
console.log(`[SUCCESS][KRAKEN]: ${tick.name} added to db!`);
});
});
loopKR();
}
}, 1100);
};
loopKR();
正如您所看到的,我正在尝试主要处理请求中出现的错误。但是我如何将它们发送到日志(我当前的代码是否正确?有更好的方法吗?)?在出现错误并打破循环后,如何自动重启循环?
使用此代码,错误未得到正确处理...出于某些原因,我收到以下消息:
TypeError:无法读取未定义的属性“body” 在apiRequest.then(fast-crypto / module / app.js:34:22) 在tryCatcher(fast-crypto / node_modules / bluebird / js / release / util.js:16:23) 在Promise._settlePromiseFromHandler(fast-crypto / node_modules / bluebird / js / release / promise.js:512:31) 在Promise._settlePromise(fast-crypto / node_modules / bluebird / js / release / promise.js:569:18) 在Promise._settlePromise0(fast-crypto / node_modules / bluebird / js / release / promise.js:614:10) 在Promise._settlePromises(fast-crypto / node_modules / bluebird / js / release / promise.js:693:18) at Async._drainQueue(fast-crypto / node_modules / bluebird / js / release / async.js:133:16) at Async._drainQueues(fast-crypto / node_modules / bluebird / js / release / async.js:143:10) 在Immediate.Async.drainQueues(fast-crypto / node_modules / bluebird / js / release / async.js:17:14) 在runCallback(timers.js:781:20) 在tryOnImmediate(timers.js:743:5) at processImmediate [as _immediateCallback](timers.js:714:5)(node:12507)UnhandledPromiseRejectionWarning:未处理的承诺 rejection(rejection id:1):TypeError:无法读取属性'name' undefined(node:12507)[DEP0018] DeprecationWarning:未处理的承诺 拒绝拒绝。在未来,承诺拒绝 未处理将以非零退出终止Node.js进程 码。 {错误:ENOENT:没有这样的文件或目录,打开 '../logs/[KRAKEN]2017-08-20T10:58:03.302Zerrorlog.txt'errno:-2, 代码:'ENOENT',系统调用:'打开',路径: '../logs/[KRAKEN]2017-08-20T10:58:03.302Zerrorlog.txt'}