我有一个用于解析一些比特币区 block 链的脚本。
我正在使用此 great lib 中的异步队列功能但代码似乎在处理过程中停止了,没有任何消息,这可能是什么原因造成的?
queue.drain 永远不会调用,因为执行只是消失了! 有没有办法找到脚本崩溃的原因?我尝试使用 Node 调试器但没有成功。
'use strict';
var request = require ('request');
var fs = require('fs');
var async = require('async');
var blocksTotal = 0, k = 0;
var data = [];
var queue = async.queue((task, callback) => {
request('https://blockchain.info/rawblock/' + task.hash, (err, response, body) => {
if (err) console.error(err);
if (response.statusCode === 200) {
let parsedBlock = JSON.parse(response.body);
//console.log('processing block [' + i + '/' + blocks.length + ']...');
parseTransactions(parsedBlock.tx);
callback(err);
};
});
}, 100);
queue.drain = () => {
console.log('all blocks processed. done.')
}
var convertTime = function(UNIX_timestamp){
let a = new Date(UNIX_timestamp * 1000);
let year = a.getFullYear();
let month = +a.getMonth()+1 >= 10 ? +a.getMonth+1 : '0' + (+a.getMonth()+1);
let date = a.getDate() >= 10 ? a.getDate() : '0'+a.getDate();
let hour = a.getHours() >= 10 ? a.getHours() : '0'+a.getHours();
let min = a.getMinutes() >= 10 ? a.getMinutes() : '0'+a.getMinutes();
let sec = a.getSeconds() >= 10 ? a.getSeconds() : '0'+a.getSeconds();
let time = hour + ':' + min + ':' + sec + ' ' + date + '/' + month + '/' + year ;
return time;
}
console.log('requesting blocks...');
//make a req to blockchain to get a neat JSON
request('https://blockchain.info/blocks/?format=json', (err, response, body) => {
if (err) console.error(err);
if (response.statusCode === 200) {
let today = JSON.parse(response.body);//get today's blocks in JSON
console.log('got blocks, parsing blocks...');
parseBlocks(today.blocks);
};
});
//parse blocks and get transactions from it
var parseBlocks = function(blocks) {
console.log('got ' + blocks.length + ' blocks...')
blocksTotal = blocks.length;
var i = 0;
blocks.forEach((block) => {
queue.push({hash: block.hash}, (err) => {
if(err) console.log(err);
i++;
//console.log('finished block ' + i + '\r');
process.stdout.write(queue.running() + ' in queue\r')
});
//request('https://blockchain.info/rawblock/' + block.hash, (err, response, body) => {
//if (err) console.error(err);
//if (response.statusCode === 200) {
//let parsedBlock = JSON.parse(response.body);
//i++;
//console.log('processing block [' + i + '/' + blocks.length + ']...');
//parseTransactions(parsedBlock.tx, i);
//};
//});
});
};
//get UNIX timestamp and transaction value and write it to file
var parseTransactions = function(transactions){
console.log('got ' + transactions.length + ' transactions from block. processing...')
transactions.forEach((transaction) => {
let value = 0;
transaction.inputs.forEach((input) =>{
if (input.prev_out) {
value += input.prev_out.value;
};
});
if (value !== 0) {
value = value.toString();
if (value.length > 8) {
value = value.slice(-0,-8) + '.' + value.substr(-8)
}else{
while(value.length !== 8){
value = '0' + value;
}
value = '0.' + value;
};
//let info = (convertTime(transaction.time) + ';' + value + '\n');
//fs.appendFile('data', info, () => {
//console.log('Data saved to file');
//});
let info = [transaction.time, value];
data.push(info);
};
});
}
最佳答案
将我的评论变成答案,因为它似乎已经找到了解决方案:
为了确保您的代码永远不会停止,您必须确保始终调用callback(err)
。如果任何代码路径可能不调用它,那么异步库将停止,因为它仍在等待最后一个异步操作来发出完成信号。
因此,您有几种方法可以使其停止:
- 如果您的
request()
操作实际上报告了错误。 - 如果您的
request()
操作实际上返回 200 以外的状态代码。 - 如果您在请求回调处理程序中的任何位置抛出异常,例如在
JSON.parse()
或parseTransactions()
中。
这是一个更强大的实现:
var queue = async.queue((task, callback) => {
request('https://blockchain.info/rawblock/' + task.hash, (err, response, body) => {
if (err) {
console.error(err);
callback(err);
}
else if (response.statusCode === 200) {
try {
let parsedBlock = JSON.parse(response.body);
//console.log('processing block [' + i + '/' + blocks.length + ']...');
parseTransactions(parsedBlock.tx);
callback(err);
} catch(e) {
callback(e);
}
} else {
callback(new Error("statuscode was: " + response.statusCode));
}
});
}, 100);
仅供引用,使用现在标准的 ES6 Promise 结构而不是带有手动回调的异步库的一个巨大优势是,它使这类东西变得更简单、更万无一失。它会自动传播错误。它会自动捕获异步异常并将其转化为错误。它使编写健壮的错误处理代码变得更加容易。
关于javascript - Node.js 脚本未完成就停止且没有声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36107700/