簡體   English   中英

Javascript承諾鏈執行不正常

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM