簡體   English   中英

JavaScript承諾停留在待處理狀態

[英]Javascript promise stuck in pending state

我是Java語言的新手,並且懷疑我有一個基本錯誤。 我想按順序運行循環,但是我使用的是Promise,但它們處於“待定”狀態。

function print(i){
    return new Promise(function(resolve,reject){
      console.log(i);
      resolve();
    });
}

counter = 0;
var sequence = Promise.resolve();

// The real while loop is much more complicated than this
while (counter < 10) {
    sequence = sequence.then(function() {
      print(counter);
    }).then(function() {
      counter += 1;
    });
}

我的問題與該問題非常相似,除了即使我調用resolve() ,我仍然陷於掛起狀態。 我究竟做錯了什么?

你有兩個問題。 比較簡單的一種是,您不返回print的結果,因此,您永遠不會等待承諾解決,然后再繼續。

更大的問題是,您的while循環正在嘗試將同步循環與promise結合在一起。 基本上,您的while循環偽代碼如下所示:

while counter < 10:
  spawn an async task
end

由於counter僅在異步任務中增加,因此while循環將永遠不會結束。 更重要的是,由於while循環永遠不會停止,因此異步任務也不會啟動,因為javascript是單線程的。

您可以使用await解決此問題,如下所示:

 function print(i) { return new Promise(function(resolve, reject) { console.log(i); resolve(); }); } async function runLoop() { let counter = 0; while (counter < 10) { const result = await print(counter); counter += 1; } } runLoop().then(() => { console.log('done'); }); 

如果您不能使用異步/等待,則可以使用array.reduce順序解決承諾。 在那種情況下,我讓print函數返回一個我們以后可以調用的函數。

function print(i) {
  return function() {
      return new Promise(function(resolve,reject){
        console.log(i);
        resolve();
      });
  }
}

然后,我們初始化空的promiseArray和計數器

const promiseArray = [];
let counter = 0;

現在,我們可以向數組添加10個打印功能。

while (counter < 10) {
    promiseArray.push(print(counter));
    counter++;
}

並不是說打印功能現在可以返回另一個功能。 我們尚未調用該函數,也未嘗試履行承諾。 如果print函數將返回一個Promise(而不是一個函數),則Promise將得到解決,並且不會被順序解決。 由於我們不能保證print(1)在print(2)之前完成。 它只會啟動一些打印調用並以任何順序解決。

為了依次解決承諾,我們使用以空promise開頭的數組reduce,對其進行解析,然后調用下一個promise函數。

promiseArray.reduce((init,curr) => {
    return init.then(curr);
},Promise.resolve())

完整的代碼段如下所示:

 function print(i) { return function() { return new Promise(function(resolve,reject){ console.log(i); resolve(); }); } } const promiseArray = []; let counter = 0; // The real while loop is much more complicated than this while (counter < 10) { promiseArray.push(print(counter)); counter++; } promiseArray.reduce((init,curr) => { return init.then(curr); },Promise.resolve()) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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