[英]Javascript promise chain executing out of order
我做了一個“promisified”版本fs.readFile
使用JavaScript的本地承諾,解決時,它解析JSON文件,並返回對象。
function readFileAsync(file, options) {
return new Promise(function (resolve, reject) {
fs.readFile(file, options, function(err, data) {
if (err) {
reject(err);
} else {
var object = JSON.parse(data);
resolve(object);
}
});
});
}
我首先嘗試自己鏈接諾言,但由於某種原因,首先會記錄諾言1中的districts.variable1
,然后在諾言3中調用comparePersonalities
,這會產生錯誤,因為用戶仍未定義,然后從諾言中記錄user.variable2
2。
var user, district;
readFileAsync(file1, 'utf8').then(function (data) {
districts = data;
console.log(districts.variable1);
}).then(readFileAsync(file2, 'utf8').then(function (data) {
user = data;
console.log(user.variable2);
})).then(function (result) {
comparePersonalities(districts, user);
}).catch(function (e) {
console.log(e);
});
我還嘗試了使用Promise.all
的另一種方法,但這仍然會導致順序錯誤和comparePersonalities
失敗。
Promise.all([readFileAsync(file1), readFileAsync(file2)]).then(function (first, second) {
districts = first;
user = second;
comparePersonalities(districts, user);
});
當在promise中記錄已解決的對象時,一切似乎都運行良好,我無法弄清楚為什么最終都會初始化所有東西,但是最后一個promise在第二個promise完成之前運行。 在鏈式承諾和Promise.all
我在做什么錯?
Promise.all
更適合您的用例。 您在回調中犯了一個錯誤:外部諾言通過結果數組 (與內部諾言的順序相同)解析,因此then(function (first, second) {...})
不正確。 試試這個
Promise.all([
readFileAsync(file1, 'utf8'),
readFileAsync(file2, 'utf8')
]).then(function (results) {
// note that "results" is an array of two values
var districts = results[0];
var user = results[1];
comparePersonalities(districts, user);
});
您每次必須返回Promises進行鏈接:
readFileAsync(file1, 'utf8').then(function(data) {
districts = data;
console.log(districts.variable1);
return readFileAsync(file2, 'utf8');
}).then(function(data) {
user = data;
console.log(user.variable2);
comparePersonalities(districts, user);
}).catch(function(e) {
console.log(e);
});
comparePersonalities(districts, user)
僅在您的可變districts
在更高范圍內聲明時才起作用。 否則,一旦達到此功能,它將是不確定的。
始終只用一個值解決承諾。 這確實很重要,並且實際上簡化了很多事情,因為您始終知道期望多少個元素。
您犯了一個錯誤,即將Promise傳遞給.then
方法,而實際上它總是希望有一個函數。 注意,片段readFileAsync(file2, 'utf8')
很好地包裝在一個匿名函數中。
var user, district;
readFileAsync(file1, 'utf8').then(function (data) {
districts = data;
console.log(districts.variable1);
})
.then(function () { return readFileAsync(file2, 'utf8') })
.then(function (data) {
user = data;
console.log(user.variable2);
}).then(function (result) {
comparePersonalities(districts, user);
}).catch(function (e) {
console.log(e);
});
但是,在這種情況下,最好使用Promise.all
方法,因為承諾會得到解決,並在下一個函數調用中很好地返回。 您的代碼段中的問題是Promise.all
總是解析一個對象,對於Promise.all
,您應該期望一個數組。 您實際上可以使用es6解構來簡化代碼:
Promise.all([readFileAsync(file1), readFileAsync(file2)])
.then(function ([districts, user]) {
comparePersonalities(districts, user);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.