2016-03-19 7 views
1

私はいくつかのビットコインブロックチェーンを解析するためのスクリプトを用意しています。Node.jsスクリプトはサウンドなしで未完成のまま終了します

私はこのgreat libから非同期キュー機能を使用していますが、処理の途中でメッセージが表示されずにコードが停止しているようですが、何が原因ですか?

実行がただ消えているので、queue.drainは呼び出しません! スクリプトクラッシュの理由を取得する方法はありますか?私はノードデバッガを使ってみましたが、成功しませんでした。解決につながっているようですので、答えに私のコメントを作る

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

code at pastebin

+0

質問には、質問に直接貼り付けられ、適切にフォーマットされたコードが含まれていなければなりません。これがスタックオーバーフローに関するここのポリシーです。 – jfriend00

+0

@ jfriend00申し訳ありません、私はちょうどエディタが好きではない、それはしばしばすべてのアイデンティティを壊す。 – Syberic

+0

あなたはいつでもここにコードを貼り付けることができます:http://jsbeautifier.org/、美しいボタンを押し、1つの余分なブロックを全てインデントし、それを貼り付けるといいです。はい、ここのエディタは、コードを書く人々の暗い年代からのものです。どれくらいのコードがここに掲載されているのか、私はそれについてこれまでに何も行われていないことに驚いていますが、私がMetaでそれについて尋ねたとき、私は理解できませんでした。 – jfriend00

答えて

1

はあなたのコードがストールしたことがないことを確認するには、あなたは常にcallback(err)を呼び出していることを確認する必要があり。コードパスがそれを呼び出せない場合、非同期ライブラリは、その最後の非同期操作がその完了を知らせるのを待っているので、ストールします。このように

、あなたはそれが停止になるだろう、いくつかの方法があります:あなたのrequest()操作は、実際にエラーが報告された場合

  1. を。あなたは、このようなJSON.parse()parseTransactions()のようにあなたの要求のコールバックハンドラ内の任意の場所に例外をスローした場合、あなたのrequest()操作が実際に
  2. 200以外のステータスコードを返した場合

ここでより堅牢な実装です:

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

FYI、代わりに手動コールバックで非同期ライブラリの今標準ES6の約束構造を使用することの大きな利点は、それがスタッフAのこの種を作ることですもっと簡単で多くのことができます。自動的にエラーを伝播します。自動的に非同期例外をキャッチし、エラーに変換します。これにより、エラー処理コードの書き込みをより簡単に行うことができます。

+0

さらに、誤った409ステータスコードによって引き起こされたエラーを言いたいと思っています。これは100スレッドで(async.queueの2番目の引数として)これを行ったからです。スレッドを10に下げると、ステータスコードの問題全体が解決されましたが、現在はエラーをさらに注意深く処理しています。 – Syberic

関連する問題