Hướng dẫn dùng asynchronize JavaScript

Đồng bộ và bất đồng bộ trong javascript mang đến cho bạn kiến thức về xử lý đồng bộ,bất động đồng bộ và các cách vận dụng trong lập trình javascript.

1. Xử lý đồng bộ [Synchronous]

Synchronous [đồng bộ / tuần tự] tức là code chương trình sẽ chạy tuần tự từ trên xuống dưới. Khi nào lệnh trên hoàn thành thì lệnh dưới mới được chạy.  Đây là cách viết code rất thường dùng.

Cái hay của nó là dễ kiểm soát quá trình xử lý. Cái hay thứ hai là dễ kiểm soát lỗi phát sinh. Còn điểm không hay của xử lý đồng bộ là gì?  Đó là do chạy theo thứ tự nên sẽ có trạng thái chờ, lệnh trên chạy quá lâu sẽ làm ảnh hướng đến các lệnh dưới.

Trong 2 ví dụ bên dưới, code chạy lần lượt từ trên xuống, lệnh trên chạy dù có lâu thì chỉ chỉ khi thực hiện xong, lệnh dưới mới chạy:

    console.log["Đời đẹp lắm"];
    console.log["Em có biết không"];
    /*Kết quả:
         Đời đẹp lắm
         Em có biết không
    */
 // ...
 thuchienNauCom[];
 thuchienChienTrung[];
 thuchienAnCom[]; 

2. Xử lý bất đồng bộ [Asynchronous]

Asynchronous [bất đồng bộ/bất tuần tự]: tức là code chương trình không hẳn tuần tự nữa, nhiều lệnh có thể thực hiện cùng lúc. Có khi lệnh dưới cho kết thúc và cho kết quả trước cả lệnh phía trên.

Cái hay của xử lý bất đồng bộ là gì? Đó là nó có thể tối ưu được sức mạnh của hệ thống, thứ hai giúp giảm thời gian chờ, giúp code chạy nhanh hơn.  Còn điểm không tốt của bất đồng bộ?  Không phải hệ thống nào cũng dùng bất đồng bộ được, thứ hai là khó làm quen xử lý và kiểm soát lỗi phát sinh.

Trong javascript, các hàm setTimeout, setInterval, fetch… là tiêu biểu cho các hàm xử lý bất đồng bộ trong javascript . Sau đây là mõt ví dụ xử lý bất đồng bộ:

    setTimeout[ [] => {console.log["Đời đẹp lắm"];} , 1000];    
    console.log["Em có biết không"];
    /*Kết quả:
        Em có biết không
        Đời đẹp lắm
    */

url=`//api.openweathermap.org/data/2.5/weather?id=1566083&appid=YOUR_API_key`;
window.fetch[url].then[ res => res.json[]].then[ data => console.log[data]];
alert["Lấy thời tiết ở HCM"];

3. Các phương án xử lý bất đồng bộ

Trong javascript có nhiều phương án xử lý bất đồng bộ : :

  • Dùng hàm Callback
  • Sử dụng Promise
  • Dùng async/await [của es6]

B. Xử lý bất đồng bộ bằng callback

Hàm callback là một hàm được truyền vào như tham số cho 1 hàm khác. Trong Javascript bạn có thể định nghĩa mới hàm có dùng callback. Và Bạn cũng có thể dùng callback trong các hàm có sẵn đã được hỗ trợ .

1. Định nghĩa hàm mới có sử dụng callback

Bạn có thể tự tạo 1 hàm sử dụng callback bằng cách nhận tenbien ở tham số sau đó thực thi tenbien[] ở nội dung của hàm.

Ví dụ 1: định nghĩa hàm xử lý chuỗi, xử lý xong thì hiện chuỗi ra.

function hienchuoi[str] {
    str = str.toUpperCase[];  
    console.log[str];
}
function xulychuoi[str, callback]{ 
    str = str.replace[/[*?][$!&]/g, ""];
    str = str.replace[/\s+/g, " "];
    str = str.trim[];
    if [callback] callback[str];
}


    str ="  Vạn * [ sự tùy ? ! &duyên$   ";
    xulychuoi[str, hienchuoi]; //VẠN SỰ TÙY DUYÊN

Ví dụ 2: Viết hàm nhập điểm, sau đó gọi hàm callback để hiển thị học lực.

    
function xuly[tenmon, callback]{
    alert["Môn đang học: " + tenmon];
    var điểm = prompt["Điểm bao nhiêu?????"];
    callback[điểm, tenmon];
}
function thongbao[d, sub]{
    if [d=9] cothuong=true; else cothuong=false;
    if [cothuong] resolve["Chúc mừng bạn"];
    else reject["Cố gắng lần sau nhé"];
}];

Hai hàm trong Promise có thể đặt tên khác mà không nhất thiết phải là resolve reject. Hàm đầu tiên [resolve] dùng để chạy khi task được đánh giá thành công nếu không thì hàm sau [reject] sẽ được gọi. Mỗi hàm chỉ được trả về 1 giá trị [mảng cũng được], nếu trả về nhiều hơn thì các giá trị sau sẽ bị bỏ qua.

4. Sử dụng promise đã tạo

Cách 1: Dùng then với 2 hàm, hàm đầu tiên được hiểu là resolve [chạy khi tác vụ trong promise OK], hàm sau được hiểu là reject [chạy khi tác vụ trong promise là fail] , hai hàm cách nhau bởi dấu phẩy.

    p.then[
        function[v1] { console.log[v1]} ,
        function[err] { console.log[err]}
     ];
    console.log["Hi"];

Cách 2: dùng then và catch

    promise
    .then[function[v1]{ console.log[v1]}]
    .catch[function[err]{ alert[err]}]

5. Các trạng thái của Promise

Mỗi đối tượng promise có các trạng thái như sau:

  • Pending [đang xử lý] : ]: là trạng thái mà promise đã tạo ra nhưng chưa được thực thi.
  • Fulfilled [resolve – đã hoàn thành] : là trạng thái mà Promise đã được thực thi và return kết quả resolve[]. Khi hàm resolve được trả về – promise gọi đến lệnh .then[] – để tiếp tục thực hiện logic tiếp theo.
  • Rejected [đã bị từ chối]: Promise đã thực thi và return kết quả reject[]. Khi hàm reject được trả về – promise gọi đến lệnh .catch[] – để tiếp tục thực hiện logic tiếp theo.

5. Lợi ích khi sử dụng Promise

  • Tránh được Callback Hell
  • Code rõ ràng, dễ đọc , dễ debug hơn

Ví dụ sau dùng callback [chứ không dùng promise] thực hiện chuyển màu màn hình sang màu red sau 5 giây, sau đó 1 giây chuyển sang blue.

setTimeout[[] => {
    document.querySelector["body"].style.background="red";
    setTimeout[[] => {
       document.querySelector["body"].style.background="blue"; 
    }, 1000];
}, 5000];

Viết theo kiểu dùng callback như trên rối , khó debug. Nếu yêu cầu thêm : sau đó 3s đổi thành green, rồi sau đó 4s đổi thành pink thì bài toán lúc này rối lắm, code sẽ cực kỳ khó nuốt.

Code sau sẽ dùng promise để giải quyết yêu cầu giống như trên: đổi màu nền sang red sau 5s rồi 1s sau đổi sang blue. Tiếp 3s sau đổi sang green, rồi 4s sau đổi sang pink.

function xuly[color, time]{
    return new Promise[function[rOK, rFail]{
        setTimeout[[] => {
           document.querySelector["body"].style.backgroundColor=color;
           rOK["Đã chuyển màu"]; 
        }, time];
    }]
}

xuly["red", 5000]
.then[[] =>xuly["blue",1000] ]    //function[]{xuly["blue",1000];}
.then[[] =>xuly["green",3000] ]    
.then[[] =>xuly["pink",4000] ]    
.catch[ function[err] { alert["Lỗi " + err]}]

Nhờ Promise mà code bất đồng bộ được xử lý dễ hiểu hơn, có vẻ đồng bộ hơn.

Ví dụ tiếp: một ngữ cảnh khác để dùng promise: nếu điểm môn js>=9 sẽ được 1 chuyến du lịch. Để biết có được đi hay không thì phải chờ 1 khoảng thời gian đến lúc thi xong. Do đó cần tạo 1 kịch bản và các hành động có thể xảy ra sau thời gian này [tạo ra promise]

Loading...

h2 = document.querySelector["h2"]; quatrinhhoc = function [diem, tg]{     return new Promise[function[resolve, reject]{         setTimeout[function[]{             if [diem>=9] resolve[diem];             else reject["Tiêu rồi"]         }, time];     }] } var diemTK = prompt["Nhập điểm coi"]; var time = prompt["Thời gian"]; quatrinhhoc[parseInt[diemTK], parseInt[time]] .then[function[mark]{ h2.innerText="Good! welcome Singapore"; }] .catch[function[err]{ h2.innerText=err; }]

6. Sử dụng nhiều .then[] liên tiếp

Bạn có thể sử dụng nhiều then liên tiếp nhau, kết quả trả về từ .then[] trên sẽ trả cho then[] dưới một cách tuần tự nếu bạn dùng promise trong các then[]. Ví dụ 1:

var p = new Promise[function[resolve, reject]{
    setTimeout[function[]{
            console.log[1];
            return resolve[];
    },1000]
}]
console.log[p];

p.then[function[]{
    return new Promise[function[resolve, reject]{
        setTimeout[function[]{
            console.log[2];
            return resolve[];
        },4000];        
    }]
}]
.then[function[]{
    return new Promise[function[resolve, reject]{
        setTimeout[function[]{
            console.log[3];
            return resolve[];
        }
        ,3000];
    }]
}]
.then[function[]{
    return new Promise[function[resolve, reject]{
        setTimeout[function[]{
            console.log[4];
            return resolve[];
        }
        ,2000];
    }]
}]

Ví dụ 2 thực hiện các công đoạn giải phương trình bậc hai gồm : nhập dữ liệu, kiểm tra, tính nghiệm , báo lỗi

ptb2 = new Promise[ function[r1, r2]{
    var a = prompt["Mời nhập số a"];
    var b = prompt["Mời nhập số b"];
    var c = prompt["Mời nhập số c"];
    r1[ [ a, b, c]];
}];

ptb2
.then[kiemtra]
.then[tinhnghiem]
.then[xuatketqua]
.catch[thongbao]    
document.getElementById["kq"].innerHTML="

Giải phương trình bậc 2

"; function kiemtra[arr]{ return new Promise[function[r1, r2]{ if [isNaN[arr[0]]==true || isNaN[arr[1]]==true || isNaN[arr[2]]==true ]{ r2["Các hệ số a ,b , c cần phải nhập số"] } else if [arr[0]>10|| arr[1]>10 || arr[2]>10 ]{ r2["Các hệ số a ,b , c phải

Bài Viết Liên Quan

Chủ Đề