Promise 提供了非同步程式設計模型,從而提高了程式碼可讀性和流程控制。然而,有時會出現意想不到的問題。這個問題探討了為什麼 Promise.all 會傳回未定義的陣列並過早解析。
有問題的程式碼遵循典型的承諾鏈模式:
<code class="javascript">const getQueries = (models, dbId, dateStart, dateEnd) => { return new Promise((resolve, reject) => { // Fetch database and perform operations .then(extractQueries, reject) .then(sortQueries, reject) .then(onlyTen, reject) .then(addText, reject) .then((queries) => { console.log("getQueries finished", queries); resolve(queries); }, reject); }); };</code>
成功完成初始操作後操作中,問題出現在addText函數中:
<code class="javascript">const addText = (queries) => { return Promise.all(queries.map((query) => { // Oops! We're missing a `return` here! models.queries.findById(query.queryId, { raw: true, attributes: ["query"], }) .then((queryFetched) => { query.text = queryFetched.query; console.log(query); return Promise.resolve(query); }, (error) => { return Promise.reject(error); }); })); };</code>
問題的根本原因在於map回呼函數中缺少return語句。 Promise.all 需要一個 Promise 物件數組,但如果沒有返回,回調會為查詢數組中的每個元素返回 undefined。
因此,Promise.all 立即解析為一個 undefined 數組,甚至在先前地圖內的實際承諾有機會解決。這種過早的解決方案會導致意外的行為和一組未定義的值。
要修正此問題,在addText 函數中的每個Promise 呼叫之前加入return 語句至關重要:
<code class="javascript">const addText = (queries) => { return Promise.all(queries.map((query) => { return models.queries.findById(query.queryId, { raw: true, attributes: ["query"], }) .then((queryFetched) => { query.text = queryFetched.query; console.log(query); return Promise.resolve(query); }, (error) => { return Promise.reject(error); }); })); };</code>
現在,Promise.all 將正確等待數組中的所有Promise解析,從而產生包含查詢結果的預期輸出。
以上是在映射中使用非同步函數時,為什麼 Promise.all 會解析為未定義值的陣列?的詳細內容。更多資訊請關注PHP中文網其他相關文章!