2017-05-09 18 views
-1

stackoverflowで見つかったコードスニペットに基づいて、ディレクトリ内のすべてのファイルを読み込み、次に処理を進めたいと思います。 私は約束を追加しましたが、これはどういうわけか動作しません。なぜ約束が最初に解決するのですか?

私のディレクトリは、2つのファイルが含まれており、コンソールログ出力は次のとおりです。
約束はreadFiles

function readFiles(dirname, onFileContent, onError) { 
    return new Promise((resolve, reject) => { 
     fs.readdir(dirname, function(err, filenames) { 
      filenames.forEach(function(filename) { 

       console.log('inside filenames'); 

       fs.readFile(dirname + filename, 'utf-8', function(err, content) { 
        onFileContent(filename, content); 
       }); 
      }); 
     }); 
    }); 
} 

var data = []; 
readFiles('datadir/', function(filename, content) { 
    console.log('inside readFiles'); 
    data.push(filename); 
}).then(
    console.log('promise resolved'); 
    //proceed handling the data-array 
); 
+0

あなたのコードであっても、セミコロンで実行されないだろうが、あなたは 'その後、(機能(){'、あなただけの 'then'を持っている必要がありますように見えますがありますと仮定。 –

+0

私はあなたの約束のポイントを見ていません。あなたはそれを決して解決せず、コールバックを使ってファイルの内容を取得しています。 – Jamiec

+0

@Jamiec –

答えて

1

内の約束は、「最初に解決しないreadFiles


内部のファイル名に
内部のファイル名を解決" console.logへの呼び出しは、最初のファイルが読み取られる前に実行されます。

resolveは約束しているので、thenは決して呼び出されません。しかしの結果がconsole.logthenに渡しています。 console.logの結果は無効です。

あなたは、問題を修正することで、これをテストすることができます。

readFiles('datadir/', function(filename, content) { 
    console.log('inside readFiles'); 
    data.push(filename); 
}).then(function(){ // NOTE: addition of function(){..} 
    console.log('promise resolved'); 
    //proceed handling the data-array 
}); 

そして、あなたはメッセージがコンソールに書き込まれることはありませんがわかります。


これはどう対処するのですか?ノード内の完全に非同期/約束ベースのコードのまわりであなたの頭を包むには、いくつかの考えが必要です。

お待ちしています。すべてあなたの約束を解決する前に、ファイルの内容を読み取ってください。これは、2つの非同期呼び出し(ファイルのリストを読んでから、その内容を個別に読み取る)が2つあるため、ややこしいことです。ファイルの読みをそれ自身の約束で包む方が簡単かもしれません。このような何か:これを行う理由は、あなたがしてPromise.all上のチェーンは、すべてのを待つことができるということです

function readDirectory(dir){ 
    return new Promise((resolve,reject) => { 
     fs.readdir(dirname, function(err, filenames) { 
      if(err) reject(err); 
      else{ 
      resolve(filenames.map(fn => dir + fn)); 
      } 
     }); 
    }); 
} 

function readFile(filePath){ 
    return new Promise((resolve,reject) => { 
     fs.readFile(filePath, "utf-8", function(err,content) => { 
      if(err) reject(err) 
      else resolve({path:filePath, content:content}) 
     }); 
    }); 
} 

それはまた、チェーン可能にするようにreaddirために同じ操作を行いますファイルの内容も。

​​

使用法:

readFileContents('datadir/').then(files => { 
    files.forEach(file => { 
     console.log(file.path, file.content.length); 
    }); 
}); 
+0

ありがとう、魅力のように動作 –

+0

['Promise'コンストラクタの反パターンを避けてください](http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-antstat-and-how-to- avoid-it)を 'readFiles'に入れてください! promiseコンストラクタを使用する 'readDir'関数を作成し、適切に' readFile'と 'readFiles'を組み合わせてください。 – Bergi

+0

@Bergi - 私は 'readFile'メソッドで何をしたのかと思っていました。 「プロミス・コンストラクターを使用する」という意味を説明できますか? – Jamiec

関連する問題