代码之家  ›  专栏  ›  技术社区  ›  esafwan

在Javascript中将多个承诺推入数组时处理单个错误

  •  1
  • esafwan  · 技术社区  · 8 年前

    我有多个使用JS promises运行的查询。我想在这些查询运行之后做一些事情。我不在乎有没有失败,只要我知道失败了。但是,在下面的代码中,当它失败时,整个代码块都不会运行。

    以下是我的代码:

    //All the promises. These are basically multiple Firebase queries.
    let promises = [];          
    promises.push(db.ref('/gifts').orderByChild("active").equalTo("true").once('value'));
    promises.push(db.ref('/coupons').orderByChild("active").equalTo("true").once('value'));
    promises.push(db.ref('/shakes_user/' + uid).once('value'));
    promises.push(db.ref('/shakes_user/' + uid + "/gift_allowed").once('value'));
    

    然后我运行以下代码:

    // Wait for all promises to resolve
    Promise.all(promises).then(function(res) {  
    
        //I'm getting the right values below
        let gifts = res[0]; //gift
        let coupons = res[1]; //coupon
        let user_data = res[2];
        let gift_allowed = res[3];
    
        }
    

    但有时,承诺中的一些引用将不存在。当这种情况发生时,这个承诺就失败了。整个功能都没有执行。我真正想要的是,一些失败值或者一些仍然返回的东西,以便我可以处理它并继续我的逻辑。

    1 回复  |  直到 8 年前
        1
  •  3
  •   CRice    8 年前

    自从 Promise.all 将拒绝如果它的任何组件承诺拒绝,你将不得不确保没有一个这样做。你可以通过添加 .catch 每一个承诺的经办人:

    let promises = [];          
    promises.push(db.ref('/gifts').orderByChild("active").equalTo("true").once('value').catch(err => {/* handle error somehow */}));
    promises.push(db.ref('/coupons').orderByChild("active").equalTo("true").once('value').catch(err => {/* handle error somehow */}));
    promises.push(db.ref('/shakes_user/' + uid).once('value').catch(err => {/* handle error somehow */}));
    promises.push(db.ref('/shakes_user/' + uid + "/gift_allowed").once('value').catch(err => {/* handle error somehow */}));
    

    为每个承诺单独添加一个catch是很好的,因为如果您选择这样做,它将允许您以不同的方式处理每个承诺。但是,如果对每个错误使用相同的错误处理代码,则可以使用 .map 要将处理程序添加到每个承诺,请执行以下操作:

    Promise.all(promises.map(prom => prom.catch(err => {/* handle error somehow */}))).then(function(res) { // <-- note the map call
        //I'm getting the right values below
        let gifts = res[0]; //gift
        let coupons = res[1]; //coupon
        let user_data = res[2];
        let gift_allowed = res[3];
    }
    

    根据你想如何处理你的错误,一种方法可能比另一种更适合我。