2016-10-17 114 views
1

我一直在試圖讓Promise.all到與承諾的列表中沒有成功而工作,所以不是隻有一個承諾,而不是一個陣列嘗試過了,我得到了同樣的問題:Promise.all不返回

let tasks = []; 
    tasks.push(function(resolve, reject){ 
    superagent 
    .post(URL_ROOT + url_path) 
    .send(data) 
    .end(function(err, res){ 
      if(err) 
      reject(err); 

      assert.equal(res.status, status.UNAUTHORIZED); //401 
      console.log('Promise completed successfully'); 
      resolve(); 
    }); 
    }); 


Promise.all([ 
    new Promise(tasks[0]) 
]).then(function(){ 
    console.log("Done"); 
    done(); 
}) 
.catch(function(reason){ 
    throw new Error(reason); 
}); 

「承諾成功完成」打印就好,但它只是掛起,'完成'從不打印。

任何幫助將不勝感激。

+4

這沒有意義。如果「Promise completed successfully」被打印,那麼「完成」也應該被打印。 – Lewis

+0

請注意,如果你的斷言拋出,你的承諾永遠不會被拒絕,並且catch語句的回調沒有意義(它可能應該調用'done'並帶有錯誤) – Bergi

+0

@Bergi我必須承認我沒有履行我的承諾像這樣,並將Promise直接添加到任務數組中。但是OP說他得到了「Promise成功完成」,所以斷言雖然錯了不能成爲這裏的問題,因爲決心肯定也會受到打擊。剝離超強的東西,確實對我有用。 OP是否可能使用某些特定的Promise庫,它不能正常工作? – Keith

回答

5

看看這個節點處理程序:

.end(function(err, res){ 
     if(err) 
     reject(err); 

     assert.equal(res.status, status.UNAUTHORIZED); //401 
     console.log('Promise completed successfully'); 
     resolve(); 
}); 

這將通話雙方rejectresolve如果有錯誤(和assertation成功)。我懷疑你的情況,所以承諾被拒絕(因爲拒絕是在解決之前調用),代碼繼續並打印Promise completed successfully

之後,許鏈運行到廢品處理程序:

.catch(function(reason){ 
    throw new Error(reason); 
}); 

但這代碼沒有做任何事情,如在承諾繼續投擲將轉化爲在產生的承諾拒絕,其承諾在這裏被遺忘了。

請嘗試以下方法驗證我的理論,看它是否記錄:

.catch(function(reason){ 
    console.log("Promise rejected"); 
    throw new Error(reason); 
}); 

爲了解決這個問題,所有你需要做的就是調整你的代碼位:

.end(function(err, res){ 
    if(err) { 
    reject(err); 
    } else { 
    resolve(); 
    assert.equal(res.status, status.UNAUTHORIZED); //401 
    console.log('Promise completed successfully'); 
    } 
}); 

所以您已將異步任務轉換爲合適的承諾(可能還需要處理.on("error", reason => reject(reason))),並在catch子句中放置一個錯誤處理程序。

如果你仍然想的錯誤傳遞給全局錯誤處理,你能做的最好的就是做一個setTimeout,所以承諾回調不能捕捉和翻譯錯誤:

.catch(function(reason) { 
    setTimeout(() => { 
    throw new Error(reason); 
    }, 0); 
}); 
+0

啊,謝謝,它現在可以工作:)我沒有意識到執行會在拒絕之後繼續執行,或者如果未經授權,err不爲空。 – Nodeocrat

+0

此外,斷言和日誌應放在'then'處理程序中,而不是在解析程序回調中。 – Bergi

+0

Crikey有這個昨天,有人假設拒絕(),短路功能。另一種選擇當然是'if(err)return reject(err);'我知道這是個人偏好,只是如果其他縮進不能防止大量的錯誤。 – Keith