使用promise处理异步javascript中的意外行为

When you are coding for sample program you might not come across the unexpected behavior. But whenever you start writing an production code, you have to account for the unexpected behavior due to incorrect data, failure in code etc. What come to your mind when you talk about handling unexpected behavior in code? If you are thinking try/catch/finally then you will definitely get what we will be discussing in this blog. If you are not aware of try/catch you can read here.

在为示例程序编码时,您可能不会遇到意外的行为。 但是,每当您开始编写生产代码时,都必须考虑由于不正确的数据,代码失败等原因导致的意外行为。当谈到处理代码中的意外行为时,您会想到什么? 如果您想尝试/抓住/最后,那么您肯定会得到我们将在此博客中讨论的内容。 如果您不了解try / catch,则可以在此处阅读。

Some times it is difficult to relate asynchronous style of coding but if you relate it with your existing synchronous style of code you will easily understand this. To handle exceptions/unexpected behavior in asynchronous programming promise provides then/catch/finally callbacks. These are exactly similar to the try/catch/finally block. There is only one difference the try/catch you need to have catch or finally whenever you are using try but in promise you can use anything independently then or catch or finally. Behavior stays mostly same.

有时很难将异步风格的编码关联起来,但是如果将其与现有的同步风格的编码关联起来,您将很容易理解这一点。 为了处理异步编程中的异常/意外行为,Promise提供了then / catch / finally回调。 这些与try / catch / finally块完全相似。 每次使用try时,您都需要try / catch或catch才有一个区别,但是承诺您可以在那时独立使用任何东西,或者catch或finally。 行为基本保持不变。

In synchronous code, try is used to write your logic where programmer expect some unexpected things to happen. Catch block you try to catch the unexpected exceptions or errors and handle it gracefully. And in finally block you write a piece of code which executed in the end no matter what. Similar to that in synchronous style, programmer writes a code which can throw an exception in then callback. Catch callback catches exception that is thrown in then callback. And finally callback will execute no matter what. Isn't that simple?

在同步代码中,try用于在程序员期望发生某些意外情况的地方编写逻辑。 捕获块,您尝试捕获意外的异常或错误并妥善处理。 在finally块中,您编写了一段代码,无论如何最终执行。 与同步样式类似,程序员编写了可以在then回调中引发异常的代码。 Catch回调捕获随后回调中引发的异常。 最后,无论如何回调都会执行。 这不是很简单吗?

As promise is mostly used in modern asynchronous JavaScript let’s understand a bit on what I mean by asynchronous behavior in promise.

由于Promise主要用于现代异步JavaScript,因此让我们对Promise中异步行为的含义有所了解。

console.log("Start of sync code..");
var my_promise = new Promise(function(resolve, reject){
console.log("Promise constructor called..");
resolve(5);
});
my_promise.then(function(async_input){
console.log("Asynchronously called : " + async_input);
});
console.log("End of sync code..");Output:
Start of sync code..
Promise constructor called..
End of sync code..
Asynchronously called : 5

If you notice in above code, promise constructor code/callback execute synchronously within the same path of execution it is in. But then callback executes in asynchronously. This is the reason why statement “Asynchronously called : 5” is called after “End of sync code..”.

如果您在上面的代码中注意到,则应保证构造函数代码/回调在它所在的相同执行路径中同步执行。但是,回调将异步执行。 这就是为什么在“同步代码结束..”之后调用语句“异步调用:5”的原因。

Same concept applies for the promise callbacks that are chained.

相同的概念适用于链接的promise回调。

console.log("Start of sync code..");
var my_promise = new Promise(function(resolve, reject){
console.log("Promise constructor called..");
resolve(5);
});
my_promise.then(function(async_input){
console.log("Asynchronous callback #1: " + async_input);
}).then(function(){
console.log("Asynchronous callback #2");
}).then(function(){
console.log("Asynchronous callback #3");
});
console.log("End of sync code..");Output:
Start of sync code..
Promise constructor called..
End of sync code..
Asynchronous callback #1: 5
Asynchronous callback #2
Asynchronous callback #3

Now you know asynchronous behavior in Promise. Coming back to our topic, let’s see how catch and finally block executes.

现在您知道了Promise中的异步行为。 回到我们的主题,让我们看看catch和finally块是如何执行的。

console.log("Start of sync code..");
var my_promise = new Promise(function(resolve, reject){
console.log("Promise constructor called..");
resolve(5);
});
my_promise.then(function(async_input){
console.log("Asynchronous callback : " + async_input);
throw new Error("Thrown in then callback..");
}).catch(function(m){
console.log("Asynchronous catch callback.." + m);
});
console.log("End of sync code..");Output:
Start of sync code..
Promise constructor called..
End of sync code..
Asynchronous callback : 5
Asynchronous catch callback..Error: Thrown in then callback..

Catch will only execute when some error is thrown in promise or then callback.

仅当在promise或回调中引发一些错误时,捕获才会执行。

If error occurs in the constructor, subsequent then callback will not be called and it will directly go to catch callback. But at the same time notice that catch is executing asynchronously. This is the reason why “Asynchronous catch callback..” executes after “End of sync code..”. Let’s see below example explaining same.

如果构造函数中发生错误,则随后的回调将不会被调用,它将直接去捕获回调。 但同时请注意catch是异步执行的。 这就是为什么“异步捕获回调..”在“同步代码结束..”之后执行的原因。 让我们看下面的例子解释。

console.log("Start of sync code..");
var my_promise = new Promise(function(resolve, reject){
console.log("Promise constructor called..");
throw new Error("Thrown in then callback..");
resolve(5);
});
my_promise.then(function(async_input){
console.log("Asynchronous callback : " + async_input);
}).catch(function(m){
console.log("Asynchronous catch callback.." + m);
});
console.log("End of sync code..");Output:
Start of sync code..
Promise constructor called..
End of sync code..
Asynchronous catch callback..Error: Thrown in then callback..

If you want to execute something no matter what then instead of repeating code in every callback you can use finally block.

如果您想执行任何操作,则可以使用finally块,而不是在每个回调中重复代码。

function doSomethingCommon(){
console.log("Do something common..");
}console.log("Start of sync code..");
var my_promise = new Promise(function(resolve, reject){
console.log("Promise constructor called..");
throw new Error("Thrown in then callback..");
resolve(5);
});
my_promise.then(function(async_input){
console.log("Asynchronous callback : " + async_input);
//doSomethingCommon();
}).catch(function(m){
console.log("Asynchronous catch callback.." + m);
//doSomethingCommon();
}).finally(function(){
doSomethingCommon();
});
console.log("End of sync code..");Output:Start of sync code..
Promise constructor called..
End of sync code..
Asynchronous catch callback..Error: Thrown in then callback..
Do something common..

You can note in below program, use of finally does not make any sense but it show that finally also executes asynchronously. And finally can also be used independently.

您可以在下面的程序中注意到,使用finally并没有任何意义,但它表明finally也会异步执行。 最后也可以独立使用。

function doSomethingCommon(){
console.log("Do something common..");
}console.log("Start of sync code..");
var my_promise = new Promise(function(resolve, reject){
console.log("Promise constructor called..");
throw new Error("Thrown in then callback..");
resolve(5);
});
my_promise.finally(function(){
doSomethingCommon();
});
console.log("End of sync code..");Output:Start of sync code..
Promise constructor called..
End of sync code..
Do something common..Uncaught (in promise) Error: Thrown in then callback..
at <anonymous>:7:11
at new Promise (<anonymous>)
at <anonymous>:5:18

If you note in above code, “Do something common..” statement is executing after execution of last line in code. But this time you will see stack trace in the end.

如果您在上面的代码中注明,则执行代码的最后一行后,将执行“做一些常见的事情。”语句。 但是这一次您将最终看到堆栈跟踪。

If then callback is used after catch callback, even after then callback that are before the catch callback throws error then callback after catch will execute.

如果在catch回调之后使用了then回调,那么即使在catch回调引发错误之前的then回调之后,也将执行catch之后的回调。

console.log("Start of sync code..");
var my_promise = new Promise(function(resolve, reject){
console.log("Promise constructor called..");
throw new Error("Thrown in then callback..");
resolve(5);
});
my_promise.then(function(async_input){
console.log("Asynchronous callback : " + async_input);
}).catch(function(m){
console.log("Asynchronous catch callback.." + m);
}).then(function(async_input){
console.log("Then callback after catch callback executes..");
}).finally(function(){
console.log("Asynchronous finally callback..");
});
console.log("End of sync code..");Output:
Start of sync code..
Promise constructor called..
End of sync code..
Asynchronous catch callback..Error: Thrown in then callback..
Then callback after catch callback executes..
Asynchronous finally callback..

翻译自: https://medium.com/@sutrave.tirumal/handling-unexpected-behavior-in-asynchronous-javascript-using-promise-b1885e6bbe01

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值