|
JavaScript ใช้ Deferred แทน Callback |
ใช้ Deferred แทน Callback การทำงานของ javascript บางอย่างต้องรองานก่อนหน้าให้เสร็จแล้วจึงเรียกให้ทำงานปัจจุบัน อย่างเช่นการเรียก ajax หรือ Xhr เป็นต้น วิธีทำแต่เดิมๆนั้นจะใช้ callback function. ตัวอย่างดังต่อไปนี้.
HTML&JS
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test ajax</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/_test/assets/css/bootstrap.min.css">
<style type="text/css">
.the-result {
border: 1px dotted #ddd;
padding: 5px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>Test ajax</h1>
<p>This demo is using normal ajax and callback.</p>
<p>Result:</p>
<div class="the-result result1"></div>
</div>
</div>
</div>
<script src="/_test/assets/js/jquery.min.js"></script>
<script src="/_test/assets/js/bootstrap.min.js"></script>
<script>
function ajaxAndCallback() {
$.ajax({
'url': 'test-ajax-deferred.php',
'method': 'GET',
'dataType': 'json',
'success': function(response) {
output = 'date is '+response.date;
output += '<br>';
output += 'time is '+response.time;
$('.result1').append(output);
delete output;
runAfterAjax1('.result1');
}
});
}
function runAfterAjax1(selector) {
$(selector).append('<br>This code run after ajax.');
runAfterAjax2(selector);
}
function runAfterAjax2(selector) {
$(selector).append('<br>This code also run after ajax.');
}
jQuery(function($) {
ajaxAndCallback();
});
</script>
</body>
</html>
วิธีข้างบนนี้ก็จะเป็นการสั่ง callback ซ้อนๆกันไป คือเรียก ajaxAndCallback() เมื่อเสร็จแล้วจึงเรียก runAfterAjax1() และเรียก runAfterAjax2() ในตัวมันเอง.
วิธีแบบนี้ข้อเสียคือจะต้องเขียน callback function ซ้อนกันไปเรื่อยๆ. เมื่อมีการดูแลแก้ไขทีหนึ่งในภายหน้าก็จะทำให้งงได้มาก และต้องมาไล่กันปวดหัวน่าดูชม.
ใช้ Deferred
อีกวิธีหนึ่งที่ในปัจจุบันนิยมใช้กันคือใช้ Deferred. (อ่านเพิ่มเติมได้ใน jQuery.Deferred()).
วิธีนี้จะทำให้ ajax หรือคำสั่งใดๆก็ตามที่ต้องรอประมวลผลให้เสร็จจริงๆเสียก่อนจึงจะเรียกฟังก์ชั่นต่อไปให้ทำงานได้ ทำการดูแลแก้ไขได้ง่ายกว่าเดิมอย่างมาก.
ตัวอย่างดังต่อไปนี้.
HTML&JS
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test ajax</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/_test/assets/css/bootstrap.min.css">
<style type="text/css">
.the-result {
border: 1px dotted #ddd;
padding: 5px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>Test ajax</h1>
<h2>Ajax using deferred</h2>
<p>This demo is using normal ajax but use deferred instead of callback.</p>
<p>Result:</p>
<div class="the-result result2"></div>
<hr>
</div>
</div>
</div>
<script src="/_test/assets/js/jquery.min.js"></script>
<script src="/_test/assets/js/bootstrap.min.js"></script>
<script>
function runAfterAjax1(selector) {
var deferred = $.Deferred();
$('.the-result').append('<br>This code run after ajax.');
deferred.resolve();
return deferred.promise();
}
function runAfterAjax2(selector) {
var deferred = $.Deferred();
$('.the-result').append('<br>This code also run after ajax.');
deferred.resolve();
return deferred.promise();
}
function ajaxAndDeferred() {
ajaxTask = $.ajax({
'url': 'test-ajax-deferred.php',
'method': 'GET',
'dataType': 'json',
})
.done(function(data, textStatus, jqXHR) {
response = data;
output = 'date is '+response.date;
output += '<br>';
output += 'time is '+response.time;
$('.the-result').append(output);
delete output;
delete response;
});
}
var ajaxTask;
jQuery(function($) {
ajaxAndDeferred();
$.when(ajaxTask)
.then(function() {
runAfterAjax1('.result2');
})
.done(function() {
runAfterAjax2('.result2');
});
});
</script>
</body>
</html>
จะเห็นว่าวิธีดังกล่าวนี้สามารถใส่ฟังก์ชั่นที่จะทำงานต่อๆกันไปภายใน .then() ได้เลย จนกระทั่งปิดท้ายด้วย .done() ทำให้การแก้ไขในภายหน้าก็ง่ายกว่ากันอย่างมาก.
หรืออีกตัวอย่างหนึ่งที่ไม่ต้องพึ่งพาตัวแปรภายนอก (ajaxTask).
HTML&JS
function runAfterAjax1(selector) {
var deferred = $.Deferred();
$('.the-result').append('<br>This code run after ajax.');
deferred.resolve();// เรียกเฉพาะเมื่อทำงานสำเร็จแล้วเท่านั้น.
return deferred.promise();
}
function runAfterAjax2(selector) {
var deferred = $.Deferred();
$('.the-result').append('<br>This code also run after ajax.');
deferred.resolve();// เรียกเฉพาะเมื่อทำงานสำเร็จแล้วเท่านั้น.
return deferred.promise();
}
function ajaxAndDeferred() {
var deferred = $.ajax({
'url': 'test-ajax-deferred.php',
'method': 'GET',
'dataType': 'json',
})
.done(function(data, textStatus, jqXHR) {
response = data;
output = 'date is '+response.date;
output += '<br>';
output += 'time is '+response.time;
$('.the-result').append(output);
delete output;
delete response;
});
return deffered;
}
jQuery(function($) {
$.when(ajaxAndDeferred())
.then(function() {
runAfterAjax1('.result2');
})
.done(function() {
runAfterAjax2('.result2');
});
});
หวังว่าบทความนี้จะเป็นประโยชน์กับทุกท่านได้ไม่มากก็น้อยครับ
อ้างอิง:
https://developer.mozilla.org/en-US/docs/Glossary/Callback_function
https://api.jquery.com/jquery.ajax/
https://api.jquery.com/jquery.deferred/
http://www.somkiat.cc/example-of-callback-and-promise/
https://stackoverflow.com/questions/11576176/wait-for-a-jquery-ajax-callback-from-calling-function
Reference : http://https://api.jquery.com/jquery.deferred/
|
|
|
By : |
mr.v
|
|
Article : |
บทความเป็นการเขียนโดยสมาชิก หากมีปัญหาเรื่องลิขสิทธิ์ กรุณาแจ้งให้ทาง webmaster ทราบด้วยครับ |
|
Score Rating : |
|
|
Create Date : |
2017-12-06 |
|
Download : |
No files |
|
Sponsored Links |
|
|
|
|
|
|