2014-06-28 59 views
1

我试图在两个编译步骤完成时运行一个函数,但成功回调不断得到调用,即使一个失败。下面的代码:当一个承诺失败时,Promises.all不会触发catch()块?

function compile(tplStr) { 
    return new Promise(function(resolve,reject) { 
    // compile template here 
    var tpl = new function(){}; 
    resolve(tpl); 
    }); 
} 

function parse(json) { 
    return new Promise(function(resolve,reject) { 
    try { 
     var obj = JSON.parse(json); 
     resolve(obj); 
    } catch(err) { 
     console.log('JSON parse failed'); 
     reject(err); 
    } 
    }); 
} 

var i = 0; 

function bothReady() { 
    $('#c').text(++i); 
} 

function oneFailed(err) { 
    console.log('oneFailed hit'); 
    $('#c').text(err.message); 
} 

var compileProm = compile($('#a').val()); 
var parseProm = parse($('#b').val()); 

Promise.all([compileProm,parseProm]).then(bothReady).catch(oneFailed); 


$('#a').on('input', function() { 
    Promise.all([compile($('#a').val()),parseProm]).then(bothReady).catch(oneFailed); 
}); 


$('#b').on('input', function() { 
    Promise.all(compileProm,parse($('#b').val())).then(bothReady).catch(oneFailed); 
}); 

code pen

当我在它记录“JSON解析失败”,但确实没有日志“oneFailed打”像我期望的JSON部分创建一个语法错误。为什么不?如果有任何承诺被拒绝,.catch块是否不应运行?

+0

[Works for me](http://codepen.io/anon/pen/kDtCa)将jQuery和RSVP添加到代码笔后。 – Bergi

+1

但是,您的代码有时会记录'oneFailed hit',但* not *'JSON.parse failed',因为您没有更新'compileProm'和'parseProm'变量。 – Bergi

+0

@Bergi啊哈!谢谢! – mpen

回答

3

当你在#b里输入某些东西时,你的代码不能正常工作,因为不是将一个迭代传递给Promise.All,而是传递2个参数。

结果是,虽然两个承诺都运行,但只有第一个结果通过all的延续被考虑到。

的代码读取

Promise.all(compileProm,parse($('#b').val())).then(bothReady).catch(oneFailed); 

而不是

Promise.all([compileProm,parse($('#b').val())]).then(bothReady).catch(oneFailed); 

PS:其他2个调用是正确的它解释了为什么这个问题似乎只发生在编辑JSON时。