問題正是你認爲它是異步代碼。
您需要移動回調中的函數,否則代碼將在創建文件之前運行。
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) {
});
你必須使用一個名爲co
小節點模塊這雖然只是npm install --save co
爲什麼你不」在用戶之後創建文件並在文件的定義中添加用戶標識? – oriaj