Promise all và các tình huống ứng dụng phổ biến

Nội dung bài viết

Promise all là một phương thức không thể thiếu trong lập trình đồng bộ đối với lập trình viên. Vẫn biết rằng Promise được sử dụng rất rộng rãi nhưng vẫn còn đâu đó những developers vẫn chưa biết vì sao Promise all lại được sủ dụng nhiều như vậy. Bài viết này sẽ làm sáng tỏ những tình huống mà bạn nên sử dụng Promise. Bài viết này sẽ không nói rõ về cú pháp của promise.all() nữa, thay vào đó thì bạn có thể đọc lại những phần trước để hiếu hơn về những khái niệm như promise all là gì? 

Và đừng dừng lại tại đó, vì ngoài promise.all thì còn có rất nhiều khái niệm khác đi kèm nữa như là Promise.race, Promise.any, Promise.allSettled. Chính vì vậy các bạn cũng nên tìm hiểu luôn.


Promise all giúp lập trình viên như thế nào?


Không còn nghi ngờ gì nữa khi promise.all() vẫn hữu dụng kể từ khi async-await ra đời ngay từ ES7. Thế nhưng nó vẫn không phải hết thời, mà còn trở nên mạnh mẽ hỡn nữa. Còn đây là 3 tình huống phố biến nhất khi sử dụng promise.all() mà tôi và dự án của mình thường sử dụng. 

Đương nhiên là có nhiều cách giải quyết khác nhau, nhưng ở đây chúng ta đang nói về promise và theo tôi bạn cũng nên hiểu nó, để đôi khi giữa đường đời tấp nập ta vô tình gặp lại promise. Để có thể hiểu được những tình huống sử dụng promise thì bạn nên hiểu về cú pháp của promise đó là điều kiện tiên quyết.


Tình huống 1: Nhiều kết quả phải được xử lý đồng thời với nhau


Để tôi lấy một ví dụ đơn giản cho các bạn xem, đây là hình ảnh của một trang page trên Facebook, điển hình là trang tips javacript, một blog học javacript mà các bạn đang theo dõi hiện nay. 

Promise all là gì?

Các bạn hình dung ra chưa? Một page được chia ra nhiều phần nhỏ, và nó không liên quan đến nhau về hiển thị dữ liệu. Chính vì vậy, những developers của Facebook cũng đã tính toán một cách tỉ mỉ để page load nhanh hơn tạo thân thiện đối với user. Tất nhiên ở đây, tôi không khẳng định là họ đã dùng promise hay không? Hay họ làm công nghệ gì? Tôi éo quan tâm, tôi chỉ quan tâm ý tưởng thực hiện của họ là hay. Và tôi sẽ mô phỏng sử dụng promise.all() để xử lý việc này. Giờ đã hiểu hơn về tình huống này chưa? Có nghĩa là tất cả các block được load một lúc, thằng nào ra trước thì làm luôn :D, chứ không cần phải đợi nữa. 

Ví dụ:

//Lấy thông tin chi tiết của page
function getDetailPage(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('Thông tin chi tiết của page tips javascript')
        }, 300)
    })
}

//Lấy thông tin giới thiệu về page 
function getInfoPage(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('lấy thông tin giới thiệu của page tips javascript')
        }, 400)
    })
}

//Lấy những bài viết mới nhất của page 
function getArticlesPage(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('Lấy những bài viết mới nhất của page tips javascript')
        }, 500)
    })
}

function initLoad(){
    // loading.show() //hiên thị icon loading lên :D 
    Promise.all([ getDetailPage(), getInfoPage(), getArticlesPage()]).then(res=>{
        console.log(res)
        // loading.hide() //Sau khi có data rồi thì hide nó và hiện thị lên thôi
    }).catch(err=>{
        console.log(err)
        // loading.hide()// Lỗi cũng hide nó đi
    })
}
//init load    
initLoad()

Đấy bạn thấy rõ hơn chưa? Một tình huống rất phổ biến trong xu thế load page hiện nay. Facebook nó dùng gì kệ nó, nhưng ý tưởng là như vậy nếu các bạn sử dụng Promise.All(). Giờ ta qua tình huống thứ 2.


Tình huống 2: Xác minh xem nhiều kết quả yêu cầu có đáp ứng các điều kiện không


Có những tình huống như hình dưới đây, đó là một form đăng ký của google. Bạn thấy đấy có nhiều trường bắt buộc phải verify. Vậy Promise sẽ giải quyết hay giúp được gì cho chúng ta đây. 

Xem ví dụ:

function verify1(content){
    return new Promise((resolve,reject)=> {
        setTimeout(function(){
            resolve(true)
        },200)
    })
}

function verify2(content){
    return new Promise((resolve,reject)=> {
        setTimeout(function(){
            resolve(true)
        },700)
    })
}

function verify3(content){
    return new Promise((resolve,reject)=> {
        setTimeout(function(){
            resolve(true)
        },300)
    })
}

Promise.all([verify1('verify1'), verify2('verify2'), verify3('verify3')]).then(result=>{
    console.log(result)//[true, true, true]

    let verifyResult = result.every(item=>item)
    //check qua xem đúng hết chưa?
}).catch(err=>{
    console.log(err)
})

Promise.all sẽ giúp chúng ta xử lý verify song song những tình huống, thằng nào chưa pass được cho về luôn. Nhấn mạnh như đầu bài viết có nói, có rất nhiều cách để thực hiện điều này, nhưng một trong đó là sử dụng promise.


Tình huống 3: Kết hợp kết quả yêu cầu và xử lý lỗi


Mô tả: Chúng tôi cần xử lý riêng logic xuất dữ liệu và xử lý lỗi của mỗi request trong khi load page. Nếu có nhiều request, chúng tôi cần viết ở nhiều chỗ đễ xử lý lỗi mà không ai mong muốn. Lấy ví dụ ở tình huống 1 để làm rõ hơn:

//Lấy thông tin chi tiết của page
function getDetailPage(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('Thông tin chi tiết của page tips javascript')
        }, 300)
    })
}

//Lấy thông tin giới thiệu về page 
function getInfoPage(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('lấy thông tin giới thiệu của page tips javascript')
        }, 400)
    })
}

//Lấy những bài viết mới nhất của page 
function getArticlesPage(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('Lấy những bài viết mới nhất của page tips javascript')
        }, 500)
    })
}

function initLoad(){
    // loading.show()
    Promise.all([
        getDetailPage().catch(err=>err),
        getInfoPage().catch(err=>err),
        getArticlesPage().catch(err=>err)
    ]).then(res=>{
        console.log(res) // ["Thông tin chi tiết của page tips javascript", "lấy thông tin giới thiệu của page tips javascript", "Lấy những bài viết mới nhất của page tips javascript"]
        
        if(res[0] === 'Thông tin chi tiết của page tips javascript'){
            //Get data success
        }else{
            //Xử lý Error tại đây..
        }
        /*
            Tương tự cho res[1] và res[2] ...
        */
        // loading.hide()
    })
}

//init load    
initLoad()

Kết luận

Trên đây là 3 tinh huống sử dụng hợp lý về promise all. Kết hợp với việc send Email với số lượng lớn ở bài trước nữa thì bạn có thể hiểu và áp dụng một cách hiệu quả và triệt để rồi đấy. Nếu như bạn nào có ý tưởng gì thì có thể comment dưới bài viết này or gửi tin nhắn qua page tips javacript. Chúng tôi luôn sẵn sàng cùng bạn. Bạn có thêm xem nhiều bài viết hơn ở anonsytick.com

Cảm ơn các bạn đã đọc bài viết.

Có thể bạn đã bị missing