2016-02-25 55 views
2

我对理解Q promise错误处理有些困惑。假设我有以下功能(仅用于演示):Q promise中的错误处理

function first() { 
    console.log('first'); 
    var done = Q.defer(); 
    done.resolve('first'); 
    return done.promise; 
} 

function second() { 
    console.log('second'); 
    var done = Q.defer(); 
    done.resolve('second'); 
    return done.promise; 
} 

function third() { 
    console.log('third'); 
    var done = Q.defer(); 
    done.resolve('third'); 
    return done.promise; 
} 

function fourth() { 
    console.log('fourth'); 
    var done = Q.defer(); 
    done.resolve('fourth'); 
    return done.promise; 
} 

function doWork() { 
    return first().then(function() { 
     return second(); 
    }).then(function() { 
     return third() 
    }).then(function() { 
     return fourth(); 
    }); 
} 

doWork().catch(function(err) { 
    console.log(err); 
}); 

一切都很顺利。

现在,如果第二,第三第四功能,我已经得到了一些错误(由一个异步调用例如抛出),我可以抓住它优雅。

例如,如果在第二,第三或第四功能,我添加:

throw new Error('async error'); 

错误被捕获。完善!

但是让我困惑的是,如果在第一个函数中引发错误,那么错误不会被捕获,并且会破坏我的执行。

请别人告诉我为什么或我做错了什么?

非常感谢!

回答

4

承诺实现仅捕获then回调中的例外情况。如果throwfirst中,该异常将会冒泡并且只会被try-catch语句捕获。

这就是为什么异步(承诺返回)功能should never throw。相反,拒绝您要退回的承诺(done.reject(…)return Q.reject(…))。如果您不信任您的功能,您可以使用Promise.resolve().then(first).…来启动您的连锁店。

+2

你也可以开始与'q.fcall(第一)。然后(二)你的链...' – the4lt

+0

@ the4lt:是的,当然,我忘了这是一个具体的Q-问题。 'resolve()。then(...)'基本上是相同的,但是更加便携。 – Bergi

+0

谢谢,现在我对它的工作原理很清楚。 – passkey1510

1

将在try块中可以分解的逻辑和在catch块中的错误包含在reject中。

var def = q.defer(); 
try { 
    // sync or async logic that can break 
} 
catch (ex) { 
    q.reject(ex); 
} 
return def;