2017-02-24 7 views
0

簡単にするために、私はnode.jsアプリケーションを短縮しました。ノードJSロジックのデバッグ

私のサーバーでは、間違ったことを試してみるためにコードのスニペットをコピーしました。論理的に言えば、それは動作するはずです。

// Subscribed to email service 
app.get('/subscribe', function(req, res) { 
    var emailExist = false; 
    // Email to add 
    var from = req.query.from; 
    // Iterate through file and check to see if the email given exist or not. 

    var readFile = fs.createReadStream("./Database/Subscription.txt"); 

    var readline = rl.createInterface({ 
     input: readFile, 
     terminal: false, 
    }); 

    readline.on('line', function(line) { 
     if (line == from) { 
      emailExist = true; 
      console.log(line + " " + emailExist); 
     } 
    }); 

    console.log("hello " + emailExist); 

    // If email dosn't exist 
    if (emailExist === false) { 
     console.log("I am false and need to be created"); 

     fs.appendFile("./Database/Subscription.txt", from + "\n", function(err) { 
      if (err) { 
       return console.log(err); 
      } 
      console.log(from + " was added to the email subscription."); 
     }); 
    } 
}); 

上記のスニペットに示されているように、ユーザーは送信した電子メールがSubscription.txtに存在するかどうかを1行ずつ読み込みます。まあ私は実際にそれの約7コピーを持っており、それはfalseからtrueにemailExist変数を変更します。ただし、falseに設定されている場合は、その関数を呼び出します。以下は私のコンソール出力です: Console Output

これはなぜ起こっているのですか?

+1

クロムをインストールします。 端末で: 'node --inspect --debug --debug-brk path/to/script.js' –

+4

特にreadlineに関するjavascriptの非同期コールバックを読みましょう。あなたのメインロジックが完了した後、あなたのreadlineコールバックが発生しています。 – DrC

答えて

0

最も簡単な解決策は、あなたがreadlineのイベントハンドラ内のすべてのものを移動する必要がある:

readline.on('line', function(line) { 
    if (line == from) { 
     emailExist = true; 
     console.log(line + " " + emailExist); 
    } 


    console.log("hello " + emailExist); 

    // If email dosn't exist 
    if (emailExist === false) { 
     console.log("I am false and need to be created"); 

     fs.appendFile("./Database/Subscription.txt", from + "\n", function(err) { 
      if (err) { 
       return console.log(err); 
      } 
      console.log(from + " was added to the email subscription."); 
     }); 
    } 
}); 

この理由は、readlineのは、端末からの入力を待たないということです。代わりに、入力された入力がある場合に呼び出すイベントハンドラ(関数on('line'))を渡します。注:readlineは誰が関数を呼び出すかを示します。あなたはreadlineに渡しているだけで、それを呼び出すことはありません。したがって、onの中の関数は、今ではなく、将来呼び出されます(これが、この種のプログラミング「先物」と呼ばれる理由の1つです)。

あなたは少し読みやすさを向上させる(およびコールバック地獄を減らす)関数にロジックをリファクタリングすることによってできます。

function processEmail (exist, callback) { 
    console.log("hello " + exist); 

    // If email dosn't exist 
    if (exist === false) { 
     console.log("I am false and need to be created"); 

     fs.appendFile("./Database/Subscription.txt", from + "\n", function(err) { 
      if (err) { 
       if (callback) callback(err); 
      } 
      else { 
       console.log(from + " was added to the email subscription."); 
       callback(null); 
      } 
     }); 
    } 
} 

readline.on('line', function(line) { 
    if (line == from) { 
     emailExist = true; 
     console.log(line + " " + emailExist); 
    } 

    processEmail(emailExist); 
}); 

約束と非同期/待つように読めるが、あることを、コードがよりよいようにする他の方法がありますコードの非同期性を取り除かないために、非同期コードがどのように機能し、どのようなコールバックが約束するのか、async/awaitを調べるのかを理解しておいてください。