> For the complete documentation index, see [llms.txt](https://javascriptuse.gitbook.io/javascript/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://javascriptuse.gitbook.io/javascript/promise-tim-hieu-ve-promise-trong-es6.md).

# \[PROMISE] Tìm hiểu về promise trong ES6

### Ví dụ 1: Giả sử ta có một tác vụ muốn delay 5s rồi in ra chữ “LẬP” tiếp đó 3s in ra chú “TRÌNH” sau cùng 2s in ra chữ “JAVASCRIPT”

```
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
	<script type="text/javascript">
		setTimeout(function(){
       console.log('LẬP');
       setTimeout(function(){
           console.log('TRÌNH');
           setTimeout(function(){
              console.log('JAVASCRIPT');
          },2000);
       },3000);
    }, 5000);
    function handleTimeout(timeout) {
      return new Promise(function (resolve, reject) {
        setTimeout(resolve, timeout);
      });
    }
    var xxx = handleTimeout(5000);
    xxx.then(function () {
      console.log('LẬP');
    })
    .then(function () {
      return handleTimeout(3000);
    })
    .then(function () {
      console.log('TRÌNH')
    })
    .then(function () {
      return handleTimeout(1000);
    })
    .then(function () {
      console.log('JAVASCRIPT');
    });
	</script>
</body>
</html>
```

### ví dụ 2:   Một trường hợp khác, nếu bạn có task là tổng hợp một thông tin lấy nhiều nguồn từ nhiều API. Không cách nào dễ dàng và tốt khi sử dụng `Promise.all` trong trường hợp này.&#x20;

```
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://code.jquery.com/jquery.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
  <script type="text/javascript">
	  // Function to fetch Github info of a user.
	  const fetchGithubInfo = async (url) => {
	    console.log(`Fetching ${url}`)
	    const githubInfo = await axios(url)
	    // API call to get user info from Github.
	    return {
	      name: githubInfo.data.name,
	      bio: githubInfo.data.bio,
	      repos: githubInfo.data.public_repos
	    }
	  }
	  // Iterates all users and returns their Github info.
	  const fetchUserInfo = async (names) => {
	    const requests = names.map((name) => {
	      const url = `https://api.github.com/users/${name}`
	      return fetchGithubInfo(url)
	        // Async function that fetches the user info.
	        .then((a) => {
	          return a // Returns the user info.
	        })
	    })
	    return Promise.all(requests)
	    //Waiting for all the requests to get resolved.
	  }
	  fetchUserInfo(['phamngoctuong', 'yyx990803', 'gaearon']).then(a => console.log(JSON.stringify(a)));
  </script>
</body>
</html>
```

![](/files/-MMcFSZQLlvyzuQSfkLv)

## Tìm hiểu về promise trong ES6

This post has been more than **4 years** since it was last updated.

Promise được đưa vào Javascript từ ES6, đây có thể coi là một kỹ thuật nâng cao giúp xử lý vấn đề bất đồng bộ hiệu quả hơn. Trước đây kết quả của một tác vụ đồng bộ và bất đồng bộ sẽ trả về một kiểu dữ liệu nào đó hoặc thực hiện một Callback Function. Với trường hợp thực hiện Callback Function thì sẽ dễ xảy ra lỗi Callback Hell, nghĩa là gọi callback quá nhiều và lồng nhau nên dẫn đến không kiểm soát được chương trình hoặc bộ nhớ không đủ để hoạt động. Và trong bài viết này chúng ta sẽ tìm hiểu về Promise, một package được đưa vào từ ES6 giúp giải quyết vấn đề Callback Hell này.

## 1. Promise là gì ? <a href="#id-1-promise-la-gi--0" id="id-1-promise-la-gi--0"></a>

* Promise sinh ra để xử lý kết quả của một hành động cụ thể, kết quả của mỗi hành động sẽ là thành công hoặc thất bại và Promise sẽ giúp chúng ta giải quyết câu hỏi "Nếu thành công thì làm gì? Nếu thất bại thì làm gì?". Cả hai câu hỏi này ta gọi là một hành động gọi lại (callback action)

## 2. Các trạng thái của promise <a href="#id-2-cac-trang-thai-cua-promise-1" id="id-2-cac-trang-thai-cua-promise-1"></a>

Khi một Promise được khởi tạo thì nó có một trong ba trạng thái sau:

* `Fulfilled`: hành động xử lý xong và thành công
* `Rejected`: hành động xử lý xong và thất bại
* `Pending`: hành động đang chờ xử lý hoặc bị từ chối

Trong đó hai trạng thái `Reject` và `Fulfilled` ta gọi là `Settled`, tức là đã xử lý xong.

## 3. Cách tạo 1 promise <a href="#id-3-cach-tao-1-promise-2" id="id-3-cach-tao-1-promise-2"></a>

* Để tạo 1 promise chúng ta sử dụng cú pháp sau:
* ```
        var promise = new Promise(function (resolve, reject) {
        });

  ```

````
Trong đó:

* `resolve` là một hàm callback xử lý cho hành động thành công.
* `reject` là một hàm callback xử lý cho hành động thất bại.
# 4. Thenable trong promise
* `Thenable` là một phương thức ghi nhận kết quả của trạng thái (thành công hoặc thất bại) mà ta khai báo ở `Reject` và `Resolve`. Nó có hai tham số truyền vào là 2 callback function. Tham số thứ nhất xử lý cho `Resolve` và tham số thứ 2 xử lý cho `Reject`.

* ```JavaScript
        var promise = new Promise(function(resolve, reject){
            resolve('Success');
            // OR
            reject('Error');
        });

        promise.then(
                function(success){
                    // Success
                },
                function(error){
                    // Error
                }
        );
````

## 5. Catch trong promise <a href="#id-5-catch-trong-promise-3" id="id-5-catch-trong-promise-3"></a>

`then` có hai tham số callbacks đó là `success` và `error`. Tuy nhiên bạn cũng có thể sử dụng phương thức `catch` để bắt lỗi. Cú pháp:

* ```
        promise.then().catch();

  ```

````

Ví dụ:
* ```JavaScript
        var promise = new Promise(function(resolve, reject){
            reject('Error!');
        });

        promise.then(function(message){
            console.log(message);
        })
        .catch(function(message){
            console.log(message);
        });
````

## 6. Một vài ví dụ ứng dụng promise <a href="#id-6-mot-vai-vi-du-ung-dung-promise-4" id="id-6-mot-vai-vi-du-ung-dung-promise-4"></a>

Giả sử ta có một tác vụ muốn delay 5s rồi in ra chữ “LẬP” tiếp đó 3s in ra chú “TRÌNH” sau cùng 2s in ra chữ “JAVASCRIPT”

* Nếu sử dụng hàm setTimeout thì chúng ta có thể viết như sau:

```
    setTimeout(function(){
       console.log('LẬP');
       setTimeout(function(){
           console.log('TRÌNH');
           setTimeout(function(){
              console.log('JAVASCRIPT');
          },2000);
       },3000);
    }, 5000);
```

* Nhìn khá là rắc rối đúng không nào. Chúng ta có thể viết lại bằng promise như sau.

```
    function handleTimeout(timeout) {
        return new Promise(function (resolve, reject) {
            setTimeout(resolve, timeout);
        });
    }

    var xxx = handleTimeout(5000);
    xxx.then(function () {
        console.log('LẬP');
    })
    .then(function () {
        return handleTimeout(3000);
    })
    .then(function () {
        console.log('TRÌNH')
    })
    .then(function () {
        return handleTimeout(1000);
    })
    .then(function () {
        console.log('JAVASCRIPT');
    });
```

Tiếp thêm 1 ví dụ ứng dụng promise. Lần này ta sẽ sử dụng FileReader để upload nhiều file ảnh. Yêu cầu là chỉ được upload những file có định dạng ảnh và đếm xem có bao nhiêu lỗi về định dạng file, bao nhiêu lỗi về load error file, bao nhiêu file được load success.

```
    <input type="file" multiple="multiple" class="upload"/>
```

```
    $(function () {
        $(document).on('change', '.upload', function (event) {
            var files = event.target.files;
            var countTypeError = 0;
            var countLoadError = 0;
            var countLoadSuccess = 0;
            var promises = [];
            $.each(files, function (index, file) {
                promises.push(fileReader(file));
            });

            var result = Promise.all(promises).then(function (value) {
                $.each(value, function (index, object) {
                    if (object.hasTypeError) {
                        countTypeError ++;
                    }

                    if (object.hasLoadError) {
                        countLoadError ++;
                    }

                    if (object.hasLoadSuccess) {
                        countLoadSuccess ++;
                    }
                });
            });

            result.then(function () {
                console.log('countTypeError', countTypeError);
                console.log('countLoadError', countLoadError);
                console.log('countLoadSuccess', countLoadSuccess);
            });
        });

        function fileReaderPromise(file) {
            return new Promise(function (resolve, reject) {
                if (/^image/.test(file.type)) {
                    var reader = new FileReader();
                    reader.onload = function () {
                        resolve({ hasLoadSuccess: true });
                    };

                    reader.onerror = function () {
                        reject({ hasLoadError: true });
                    };
                } else {
                    reject({ hasTypeError: true });
                }
            });
        }
    });
```

Hy vọng qua bài viết này sẽ giúp bạn hiểu thêm về promise trong ES6

Nguồn tham khảo: <https://viblo.asia/asvenus/posts/p1PvQ3JAMldr>

<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://javascriptuse.gitbook.io/javascript/promise-tim-hieu-ve-promise-trong-es6.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
