問題はまさにそれが非同期コードだと思います。
コールバックの内部で関数を移動する必要があります。そうしないと、ファイルが作成される前にコードが実行されます。
JavaScriptは次の行に移動する前に待機しないため、JavaScriptは次の行が完了したかどうかに関係なく実行されます。移動する前に待つ感覚はありません。
基本的には、移動する前にファイルが保存されるのを待たずに、まだ存在しないものを追加しています。
これはちょうどthen
コールバックの内側にコードを移動、しかし働くだろう:
var files = [];
var file1 = models.File.build();
file1.name = "JPEG";
file1.save().then(function() {
files.push(file1);
var file2 = models.File.build();
file2.name = "PNG";
file2.save().then(function() {
files.push(file2);
var newUser = models.User.build();
newUser.email = email;
newUser.save().then(function (usr) {
files.forEach(function (item) {
newUser.addFile(item);
});
});
});
});
しかし、それは厄介です。代わりに、あなたはこのような連鎖約束することができます:
var files = [];
var file1 = models.File.build();
file1.name = "JPEG";
file1.save()
.then(function(file1) {
files.push(file1);
var file2 = models.File.build();
file2.name = "PNG";
return file2.save();
})
.then(function(file2) {
files.push(file2);
var newUser = models.User.build();
newUser.email = email;
return newUser.save();
})
.then(function(newUser) {
files.forEach(function(item) {
newUser.addFile(item);
});
});
は、今では少しクリーナーが、まだ少し厄介とも少し混乱です。したがって、次のようにジェネレータ関数を使用することができます。
var co = require('co');
co(function*() {
var files = [];
var file1 = models.File.build();
file1.name = "JPEG";
yield file1.save();
files.push(file1);
var file2 = models.File.build();
file2.name = "PNG";
yield file2.save();
files.push(file2);
var newUser = models.User.build();
newUser.email = email;
newUser.save();
files.forEach(function(item) {
newUser.addFile(item);
});
});
これではるかに優れています。
緊密に見て、あなたは何が起こっているかを見ます。 co
は、基本的にアスタリスクがアスタリスクの*
のジェネレータ関数を受け入れます。これは、yield
式のサポートを追加する特別な関数です。
yield
式は基本的に、移動前にthen()
コールバックが呼び出されるのを待っており、then
コールバックに引数がある場合、それも返します。
var gif = yield models.File.create({
name: 'gif'
});
の代わり:
models.File.create({
name: 'gif'
}).then(function(gif) {
});
あなたが「ドン理由だけnpm install --save co
かかわらず、このために
co
と呼ばれる小さなノードモジュールを使用する必要がだからあなたのような何かを行うことができますユーザーの後にファイルを作成し、ユーザーIDをfileの定義に追加しますか? – oriaj