Javascript 为什么我不能加入一个承诺。抓住处理者?
为什么我不能在catch回调中抛出一个Javascript 为什么我不能加入一个承诺。抓住处理者?,javascript,asynchronous,promise,throw,es6-promise,Javascript,Asynchronous,Promise,Throw,Es6 Promise,为什么我不能在catch回调中抛出一个错误,让进程像处理任何其他作用域中的错误一样处理该错误 如果我不执行console.log(err)任何内容都不会打印出来,我也不知道发生了什么。这个过程刚刚结束 例如: function do1() { return new Promise(function(resolve, reject) { throw new Error('do1'); setTimeout(resolve, 1000) }); }
错误
,让进程像处理任何其他作用域中的错误一样处理该错误
如果我不执行console.log(err)
任何内容都不会打印出来,我也不知道发生了什么。这个过程刚刚结束
例如:
function do1() {
return new Promise(function(resolve, reject) {
throw new Error('do1');
setTimeout(resolve, 1000)
});
}
function do2() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error('do2'));
}, 1000)
});
}
do1().then(do2).catch(function(err) {
//console.log(err.stack); // This is the only way to see the stack
throw err; // This does nothing
});
如果回调在主线程中执行,为什么
错误会被黑洞吞没?这里需要了解的重要事项
then
和catch
函数都返回新的promise对象
无论是抛出还是明确拒绝,都会将当前承诺移动到拒绝状态
由于然后
和捕获
返回新的承诺对象,因此可以将它们链接起来
如果您在承诺处理程序中抛出或拒绝(然后
或捕获
),它将在链接路径下的下一个拒绝处理程序中处理
正如jfriend00所提到的,then
和catch
处理程序不是同步执行的。当处理程序抛出时,它将立即结束。因此,堆栈将展开,异常将丢失。这就是为什么抛出异常会拒绝当前的承诺
在您的例子中,您通过抛出一个错误
对象来拒绝内部do1
。现在,当前承诺将处于拒绝状态,控制权将被转移到下一个处理程序,在我们的例子中是,然后是
由于then
处理程序没有拒绝处理程序,因此根本不会执行do2
。您可以使用控制台中的console.log
来确认这一点。由于当前承诺没有拒绝处理程序,因此它也将被拒绝,并带有来自上一个承诺的拒绝值,控制权将被转移到下一个处理程序,即catch
当您执行console.log(err.stack)时,catch
是一个拒绝处理程序代码>在它里面,您可以看到错误堆栈跟踪。现在,您正在从中抛出一个错误
对象,因此catch
返回的承诺也将处于拒绝状态
由于您尚未将任何拒绝处理程序附加到捕获
,因此无法观察拒绝
你可以把链条分开,更好地理解这一点,就像这样
var promise = do1().then(do2);
var promise1 = promise.catch(function (err) {
console.log("Promise", promise);
throw err;
});
promise1.catch(function (err) {
console.log("Promise1", promise1);
});
您将获得的输出类似于
Promise承诺{[Error:do1]}
承诺1承诺{[Error:do1]}
在catch
处理程序1中,您将得到promise
对象的值作为拒绝
同样,由catch
处理程序1返回的承诺也被拒绝,其错误与promise
被拒绝的错误相同,我们正在第二个catch
处理程序中观察它。此处需要了解的重要事项
then
和catch
函数都返回新的promise对象
无论是抛出还是明确拒绝,都会将当前承诺移动到拒绝状态
由于然后
和捕获
返回新的承诺对象,因此可以将它们链接起来
如果您在承诺处理程序中抛出或拒绝(然后
或捕获
),它将在链接路径下的下一个拒绝处理程序中处理
正如jfriend00所提到的,then
和catch
处理程序不是同步执行的。当处理程序抛出时,它将立即结束。因此,堆栈将展开,异常将丢失。这就是为什么抛出异常会拒绝当前的承诺
在您的例子中,您通过抛出一个错误
对象来拒绝内部do1
。现在,当前承诺将处于拒绝状态,控制权将被转移到下一个处理程序,在我们的例子中是,然后是
由于then
处理程序没有拒绝处理程序,因此根本不会执行do2
。您可以使用控制台中的console.log
来确认这一点。由于当前承诺没有拒绝处理程序,因此它也将被拒绝,并带有来自上一个承诺的拒绝值,控制权将被转移到下一个处理程序,即catch
当您执行console.log(err.stack)时,catch
是一个拒绝处理程序代码>在它里面,您可以看到错误堆栈跟踪。现在,您正在从中抛出一个错误
对象,因此catch
返回的承诺也将处于拒绝状态
由于您尚未将任何拒绝处理程序附加到捕获
,因此无法观察拒绝
你可以把链条分开,更好地理解这一点,就像这样
var promise = do1().then(do2);
var promise1 = promise.catch(function (err) {
console.log("Promise", promise);
throw err;
});
promise1.catch(function (err) {
console.log("Promise1", promise1);
});
您将获得的输出类似于
Promise承诺{[Error:do1]}
承诺1承诺{[Error:do1]}
在catch
处理程序1中,您将得到promise
对象的值作为拒绝
同样,由catch
处理程序1返回的承诺也被拒绝,其错误与promise
被拒绝的错误相同,我们在第二个catch
处理程序中观察它。根据:
d。如果调用然后抛出异常e,
A.如果调用了resolvePromise或rejectPromise,请忽略它
B否则,以e为理由拒绝承诺
这意味着,若您在函数中抛出异常,那个么
函数将被捕获,您的承诺将被拒绝catch
在这里没有意义,它只是的快捷方式。然后(null,function(){})
我猜你想不经处理地登录
.catch(function(err) { setTimeout(function() { throw err; }); });
...
throw new Error('My error message');
})
.catch(function (err) {
console.error(err.stack);
process.exit(0);
});
.catch(function(err) { setTimeout(function() { throw err; }); });
return new Promise((resolve, reject) => {
reject("err");
}).catch(err => {
this.emit("uncaughtException", err);
/* Throw so the promise is still rejected for testing */
throw err;
});
function throw_promise_error (error) {
return new Promise(function (resolve, reject){
reject(error)
})
}
}).then(function (input) {
if (input === null) {
let err = {code: 400, reason: 'input provided is null'}
return throw_promise_error(err)
} else {
return noterrorpromise...
}
}).then(...).catch(function (error) {
res.status(error.code).send(error.reason);
})