2017-05-22 21 views
1

我有以下函數返回一個承諾:在arr.forEach()語句的回調中拒絕承諾是否會停止迭代?

function someFn() { 
    // Making use of Bluebird's Promise.all() 
    return Promise.all([promise1, promise2]).then(function(results) { 
     results.forEach(function(result) { 
      return promiseReturningFn(); // Returns a Promise 
     }); 
    }).catch(function(err) { 
     console.log(err); 
    }); 
} 

我有一個關於這段代碼的兩個問題:

  1. 在一個場景中任何forEach()迭代的promiseReturningFn()不合格的,將被拒絕被catch()聲明捕獲?
  2. 如果第一次迭代的promiseReturningFn()拒絕,迭代是否會停止,意味着將不會爲結果數組中的第二個元素調用回調?如果這是真的,那麼失敗後控制流將傳遞給catch()聲明?
+0

如果你在'forEach'回調中拋出錯誤,那麼它會拒絕承諾。如果你想返回一個承諾,你需要使用經典的'for'(或'while')循環,而不是'forEach'函數。 – SeregPie

+0

不,你[不能用'forEach'](https://stackoverflow.com/q/37576685/1048572) – Bergi

+1

你在尋找藍鳥的'Promise.map'或'Promise.each' – Bergi

回答

3

在您的兩個問題:

  1. 在一個場景中任何的foreach()迭代的promiseReturningFn()不合格品,會拒絕被捕捉()語句抓?

沒有,因爲你不returnthen回調承諾,但在forEach回調,而後者沒有任何效果 - 這樣的返回值被遺忘丟失。

  • 如果在第一次迭代的promiseReturningFn()拒絕,將迭代停止,這意味着回調不會被調用的結果陣列中的第二元件?如果這是真的,那麼失敗後控制流將傳遞給catch()語句嗎?
  • 不,迭代不會停止。您甚至不會同步瞭解拒絕情況,因爲此信息只能異步使用(忽略bluebird允許同步檢查)。

    這可能是你應該如何編寫它,假設你允許promiseReturningFn已經被上解決承諾執行時,另一種是尚未解決:

    function someFn() { 
        // Making use of Bluebird's Promise.all() 
        return Promise.all(
         [promise1, promise2].map(p => p.then(promiseReturningFn)) 
        }).catch(function(err) { 
         console.log(err); 
        }); 
    } 
    

    或者,如果你真的需要數組承諾全部解決您開始執行promiseReturningFn他們面前的,那麼這樣做:

    function someFn() { 
        // Making use of Bluebird's Promise.all() 
        return Promise.all([promise1, promise2]).then(results => { 
         return Promise.all(results.map(promiseReturningFn)); 
        }).catch(function(err) { 
         console.log(err); 
        }); 
    } 
    

    在這兩種情況下,解答您的兩個問題現在:

    • 是的,如果內心承諾拒絕,catch回調將被執行。

    • 不,迭代不會停止,因爲承諾的結果只是異步知道的,所以到那時循環(map)已經完全執行了。

    要回答「是」第二個問題,並停止呼叫正在以promiseReturningFn發時之前返回承諾拒絕,你必須連載他們,再次調用promiseReturningFn前等待一個承諾履行:

    function someFn() { 
        // Making use of Bluebird's Promise.all() 
        return Promise.all([promise1, promise2]).then(results => { 
         return (function loop(i, p) { 
          return i >= results.length ? p 
           : p.then(_ => loop(i+1, promiseReturningFn(result[i]))); 
         })(0, Promise.resolve()); 
        }).catch(function(err) { 
         console.log(err); 
        }); 
    } 
    
    +0

    在第一個代碼示例中,如果我理解正確,在執行'map()'之後,我最終會調用'Promise.all([promiseReturningFn,promiseReturningFn])',對嗎?如果我對此正確,'Promise.all()'調用的'then()'語句會收到一個數組,其中包含來自'[promiseReturningFn,promiseReturningFn]'的已解決的承諾。我的理解是否正確? –

    +0

    是的,這是正確的。 – trincot