Sweet date
Xiao Ming, a programmer, is very happy today, because today is the one-year anniversary of his relationship with his girlfriend. It is well known that it is difficult for programmers to find girlfriends, and Xiao Ming is currently the only single programmer in his office, making him the envy of many programmers. Xiaoming’s work efficiency today is very high, the keyboard is going to fly up, the whole office is ringing his happy keyboard tapping sound. By the end of the day, Xiao Ming had already submitted the code and rushed downstairs to the appointment — of course, he did not forget to buy flowers.
His girlfriend is very happy to see Xiao Ming, the arrangement of the day two people have long been planned. A couple of young men, recalling the experience of the year, talked sweetly all the time — and they attracted envious glances from people wearing backpacks and plaid shirts.
The phone rang
At 9 o ‘clock in the evening, when the romantic dinner was over, Xiao Ming’s girlfriend said: “Let’s go back!” Xiao Ming got the message and was about to walk out holding his girlfriend’s hand when the phone rang! The phone is ringing! The phone is ringing! Xiao Ming had a foreboding in his heart. He pulled back his hand and took out his cell phone from his pocket. When he saw the name on the phone, he freaked out! That was the call from their leader. “Xiaoming, hurry back to the company, the code you submitted today has a Bug!” “Er, is it urgent? “Emergency! Is it not urgent to call you?” “That…… I’ll be right back.” Xiao Ming looked helplessly at his girlfriend. “The leader let me go back to fix the Bug!” “Can’t you go tomorrow? We’re dating!” The girlfriend looked unhappy. “No! When we programmers find a Bug, we need to fix it immediately!” With that, Xiao Ming picked up his backpack and hurried to the company, leaving his girlfriend standing there. Xiao Ming did not hear his girlfriend’s words: “I think we are not suitable…”
Get to the point
The above story is very common in our daily life. Isn’t fixing bugs what we programmers live on? In fact, one thing is interrupted quite often, even in network requests. For example, you enter a page, the web request is in progress, and then the user exits the page. If it’s a simple request, fine, but if you’re downloading a file and you’re making a series of requests, it’s nice to be able to cancel the request.
Dio provides a CancelToken mechanism to cancel outstanding requests. Each request can carry a CancelToken object, and when the CancelToken’s cancel method is called, the request is notified to stop the current request, thus interrupting the request. This is like xiaoming is dating, was called by the leader to change the Bug, his date is equivalent to the bubble!
The use of CancelToken
Let’s start with a simple example, starting with the optional cancelToken parameter in our HttpUtil class methods and displaying a prompt when cancellations are detected.
static Future sendRequest(HttpMethod method, String url,
{Map<String.dynamic> queryParams,
dynamic data,
CancelToken cancelToken}) async {
try {
/ /... Omit request code
} on DioError catch (e) {
// Check if the error is caused by a cancellation request, if it is printed as a cancellation alert
if (CancelToken.isCancel(e)) {
EasyLoading.showInfo('The leader called you back to change the Bug! ');
} else{ EasyLoading.showError(e.message); }}on Exception catch (e) {
EasyLoading.showError(e.toString());
}
return null;
}
Copy the code
Then we simulate a cancellation request situation. We are requesting a list of articles from the digger’s personal home page, first creating a CancelToken object and then passing it to the corresponding request. Immediately after the request is made, we call the cancel method to cancel the request. Async and await cannot be used here. Because the await waits for the request to complete, the Future’s THEN method (similar to a Promise) is used here. After receiving the response, we determine whether the request was cancelled according to the isCancelled property of the CancelToken object and update the status variable _hasBug.
void _bugHappened() {
CancelToken token = CancelToken();
JuejinService.listArticles('70787819648695', cancelToken: token)
.then((value) => {
setState(() {
_hasBug = token.isCancelled;
})
})
.onError((error, stackTrace) => {print(error.toString())});
token.cancel();
}
Copy the code
_hasBug is used to control the interface display, indicating whether there is a Bug, if there is no Bug that Xiaoming can continue to date, if there is a Bug that Xiaoming has to go back to the company to change the Bug. We trigger a bug event with a button.
class _AppointmentPageState extends State<AppointmentPage> {
bool _hasBug = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_hasBug ? 'Damn the Bug! ' : 'On a date... ',
style: Theme.of(context).textTheme.headline4),
),
body: Container(
child: Center(
child: Image.asset(_hasBug ? 'images/bug.png' : 'images/dating.png'), ), ), floatingActionButton: IconButton( icon: Icon(Icons.call), onPressed: () { _bugHappened(); },),); }/ /...
}
Copy the code
The results
The running result is as shown in the figure below, you can see that the request was cancelled after clicking the button — Xiaoming has to go back to change the Bug (ten thousand grass muddy horses floating in xiaoming’s heart)!
The practical application
If we want to cancel an outstanding request before exiting the page, we can use the CancelToken to do so. We can call the CancelToken cancellation method in the Deactivate method of the State lifecycle function (which is called before dispose). To demonstrate this, let’s go to Github, a site with slow requests. Since the CancelToken object is used in different ways, it needs to be defined as a member attribute. The complete code is as follows.
class _AppointmentPageState extends State<AppointmentPage> {
bool _hasBug = false;
CancelToken _token;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_hasBug ? 'Damn the Bug! ' : 'On a date... ',
style: Theme.of(context).textTheme.headline4),
),
body: Container(
child: Center(
child: Image.asset(_hasBug ? 'images/bug.png' : 'images/dating.png'), ), ), floatingActionButton: IconButton( icon: Icon(Icons.call), onPressed: () { _bugHappened(); },),); }void _bugHappened() {
_token = CancelToken();
HttpUtil.get('https://www.github.com', cancelToken: _token)
.then((value) => {
if (mounted)
{
setState(() {
_hasBug = _token.isCancelled;
})
}
})
.onError((error, stackTrace) => {});
}
@override
void deactivate() {
if(_token ! =null) {
_token.cancel('dispose');
}
super.deactivate(); }}Copy the code
The business process is as follows:
- After entering the screen, click the phone icon at the bottom to start the request
- Click to return to the interface to check whether _token is empty. If it is not empty, call the cancel method to cancel the request. The cancel method can take an optional argument for the reason the table name is cancelled.
If the network isn’t working well and your hands are fast enough (that’s where your king skills come in handy), you’ll see an alert on return saying our request has been canceled.
Note here that since we used the setState method in the THEN callback of the network request, this method cannot be called after dispose, otherwise it may cause a memory leak. If mounted is true, it is not disposed, and it is safe to call setState.
In the next article, we will look at the source code of Dio and see how the CancelToken is implemented.
Afterword.
Counsel each programmer, important words say three times: the appointment please remember to turn off! Date please remember to turn off! Date please remember to turn off!