2017-07-13 22 views
0

この質問はかなり似ているようですが、私はそれを実装しようとしましたが、私はそれを実装しようとしましたが、私のコードで答えてください。 similar questionJavaScriptのコールバック関数でコールバック関数の変数を割り当てる方法

今ここには私の問題ですが、私は、コードのこの部分があります

var fs = require('fs'); 
var index = JSON.parse(fs.readFileSync('../data/7XXX7/index.json', 'utf8')); 
window = {}; 
var indicators = require('./indicators'); 
var parser = new window.patient.Indicator('tes', 'test'); 
var i = 0; 

function create_indicators() { 
    var result = []; 
    fs.readdirSync('../data/7XXX7/files/').forEach(file => { 
     fs.readFile('../data/7XXX7/files/' + file, 'utf8', function (err, data) { 
      if (err) 
       throw err; 
      let $ = {}; 
      $.poids = parser.poids(data); 
      $.taille = parser.taille(data); 
      $.temperature = parser.temperature(data); 
      $.tension = parser.tension(data); 
      $.pouls = parser.pouls(data); 
      $.ps = parser.ps(data); 
      $.saturation = parser.saturation(data); 
      for (var j in index.files) 
      { 
       if (index.files[j].name === file) 
       { 
        $.id = index.files[j].name; 
        $.date = index.files[j].date; 
        $.name = index.files[j].IntituleSession; 
        break; 
       } 
      } 
      if ($.poids || $.taille || $.temperature || $.tension || $.pouls || $.ps || $.saturation) 
      { 
       result.push($); 
       console.log(result); // print the actual state of result 
//    console.log(i); prints 0 then 1 then ... 
       i++; 
      } 

     }); 
     console.log(i); // prints 0 
    }); 
    console.log(result); // prints [] 
    return result; 
} 

let result = create_indicators(); 
console.log(result); // prints [] 

をそして、それは表示されます。

[] 

はなぜreadFileの中にコールバック関数は、それ自身の変数を持っているのでしょうか?それは非同期なのですか?しかし、私がreadFileSyncを使うと、それもうまくいきません。

私はそれに入れたすべての値を取得する方法は?私がresult.push($)の後にログ結果をコンソールするとき。それは私のパーサではないので、私は適切にインデントされています。ここで

+0

[非同期呼び出しからの応答を返すにはどうすればよいですか?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-コール) – Li357

答えて

0

あなたのコードは、ファイルが読み込まれるのを待つことなく、結果がresultにプッシュされます。配列内の項目に対して非同期操作を行っているところでは、約束を使用してPromise.all()を使用して、結果を使用する前に各ファイルが読み込まれ処理されるのを待つことをお勧めします。

function create_indicators() { 
    const result = fs.readdirSync('../data/7XXX7/files/').map(file => 
     new Promise((resolve, reject) => { 
      fs.readFile('../data/7XXX7/files/' + file, 'utf8', (err, data) => { 
       if (err) reject(err); 
       // do whatever 
       if ($.poids || /* ... */ $.saturation) { 
        // ... 
        resolve($); // instead of `result.push($);` 
       } else { 
        resolve(); // can't reject for `Promise.all()` to work 
       } 
      }) 
     })); 
    return Promise.all(result).then(items => items.filter(item => item)); 
} 

create_indicators().then(indicators => { 
    // do something with your list of indicators 
}).catch(err => { 
    // handle error 
}); 

これは、ファイルが処理されたときに解決されるディレクトリ内の各ファイルに対して約束を作成します。あなたの条件が満たされていない場合は1つまたは何かがある場合はアイテムで解決し、エラーがある場合は拒否します(throwと同等の約束)。あなたの条件を満たす項目だけが必要なので、Promise.all()の結果をフィルタリングして配列内のundefinedを取り除くことができます(fs.readFileコールバックの状態チェックを取り除いて代わりに行うこともできます)。あなたが望むならばフィルター)。これは、フィルタリングされたリストで解決する約束を返します。

0

はあなたの問題です:

fs.readFileSync('../data/7XXX7/files/' + file, 'utf8', function (err, data) { 

readFileSyncは、引数としてコールバックを取ることはありません。データを返すか、例外が発生します。これは同期的です(名前の「同期」が示すように)、非同期であるかのように使用しています。

は、ドキュメントを参照してください:

+0

ああ私は実際には、質問のためにそれを削除することを忘れていたことを知っています。私のコードがかなり悪いように見える場合は、これを何時間も働いているので、私はちょっと心を失い、ブルートフォースのことを始めました。 –

0
  1. readFileSyncがコールバックしません。それは同期的です。
  2. fs.readdirを使用して、読みたいファイルのリストを取得します。 How do you get a list of the names of all files present in a directory in Node.js?
  3. コールバックの仕組みを理解する必要があります。

readFileSyncはコールバックしません。終了されようとしているとき、あなたがわからないので、あなたが渡す、あなたは非同期操作を行っているときにコールバックが非同期fs.readFilefs.readdir

にどのように動作するかを説明するのに役立つかもしれませんパラメータ内の関数(コールバック)を呼び出し、操作の最後に実行します。

fs.readFile('/etc/passwd', function (err, data) { 
    if (err) throw err; 
    console.log(data); 
}); 

が実行終了したとき(ERRデータ)関数を実行し、2番目のパラメータとしてデータに通過する上記のコードでfs.readFile。エラーが発生した場合、エラーの最初のパラメータとして渡されます。

また、解析が終了したときの処理を定義するコールバック関数を取得することもできます。コールバックはエラーと結果を取る必要があります。

読む(エラーが必要な場合): http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/

をだからあなたのcreate_indicators機能は、コールバック関数を取る必要があります。

fs = require("fs") 
function create_indicators(folderPath, callback) { 
    let result = []; 
    fs.readdir(folderPath, (err, files) => { 
     if (err) 
      callback(err, null); //pass the error to callback if there is any 
     else { 

      files.forEach((file, index, filesArray) => { 
       fs.readFile(file, (err, data) => { 
        if (err) 
         callback(err, null); //pass the error to callback if there is any 
        else { 

         //.....parse.... 
         result.push(data); 

         // pass data to callback function when it is the last result 
         if (result.length == filesArray.length) 
          callback(null, result); 

        } 
       }); 
      }); 

     } 
    }) 
} 

これを呼び出すときは、結果とエラーを関数として渡します。

create_indicators(".", function(err,result){ 
    if (err) 
     console.error("Got error:", err); 
    else 
     console.log("Got result:", result); 
     //do what you want with the final result 
    }) 

コールバックが有効になったら、プロミスを調べて、この手順をよりクリーンで簡単にします。 Read:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

+0

これは結果を返す前にファイルが読み込まれるのを待つことはありません。 –

+0

申し訳ありませんが、間違いました:)今すぐ動作する必要があります。 –

関連する問題