Understand Promise in 5 minutes

# Reference
http://blog.kueiapp.com/en/programming/understand-promise-in-5-minutes-javascript/

# Synchrounous and asynchrounous requests

A process need to wait for another process got finished and then does something else in synchrounous model; in contract, asynchrounous one does not. *( It will describe with sync and async below.)*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541166/a5e197dd-0c76-9fe3-a514-7e2209def1f0.png)
> [image source](http://tutorials.jenkov.com/images/software-architecture/software-architecture-introduction-3.png)


> [Concept of async programming](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Introducing)


###### Sample for async functions

```js
function first(){
  // Simulate a code delay
  setTimeout( function(){
    console.log(1);
  }, 500 );
}
function second(){
  console.log(2);
}
first();
second();
// 2
// 1
```

### Non-blocking environment
- how to handle the result of each async processes below??
- how does our system know the async process is done??
![Async requests(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541166/3833e3b0-efec-4b98-9445-6566a2ccbe97.png)

## To handle async processes
> [what is ES6, ES7, ECMAScript2015...](https://codeburst.io/javascript-wtf-is-es6-es8-es-2017-ecmascript-dca859e4821c)

###### Method 1: [Callback function](https://codeburst.io/javascript-what-the-heck-is-a-callback-aba4da2deced) // ES4 standard

```js
function first(subject, callback) {
  console.log(subject + " 1");
  callback();
}
function second(){
  console.log('Call 2');
}
first('Hello', second);
// Hello 1
// Call 2
```

> [what is Callback hell](http://callbackhell.com/)

###### Real example 1: [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) ES5 standard

```js
const oReq = new XMLHttpRequest();

// Handle async responses
oReq.addEventListener("load", function () {
  console.log('show: '+this.responseText);
});
oReq.upload.addEventListener("progress", function(){
  console.log('updateProgress');
});

// Async request
oReq.open("GET", "http://www.example.org/example.txt");
oReq.send();
```

###### Method 2: [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) ES6 standard

An object to wrap and unwrap objects and functions asynchronously

```js
// Wrap async function using Promise
function timeoutPromise(interval) {
  return new Promise((resolve, reject) => {
    setTimeout(function(){
      console.log("processing");
      resolve('processed');
    }, interval);
  });
};

// Use then(), catch() to unwrap Promise when calling
timeoutPromise(1000).then(function(result) {
  console.log(result); // processing, processed
  console.log('done'); // done
});

// Unwrap Promise sequentially
Promise.all([timeoutPromise(1000), timeoutPromise(1000)]).then(function(values) {
  console.log(values);
});
// processing, processing, ['processed','processed']

```

###### Real example 2a: [jQuery](https://api.jquery.com/jQuery.get/) 

```js
// Async request
$.get('http://www.example.org/example.json', function(response){
  console.log(JSON.stringify(response));
});
```

###### Real example 2b: [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) HTML5 standard

```js
// Async request
fetch('http://www.example.org/example.json')
  .then((response) => {
    return response.json();
  })
  .then((jsonContent) => { // extract json
    console.log(jsonContent);
  });
```

###### Method 3: [async/await](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await) ES7 candidate

For unwrap Promise object easily

```js
function timeoutPromise(interval) {
  return new Promise((resolve, reject) => {
    setTimeout(function(){
      console.log("processing");
      resolve();
    }, interval);
  });
};
// Unwrap Promise sequentially
async function timeTest() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  console.log('done');
}

timeTest(); // processing, processing, done 
```

###### Summary
Because sending requests asynchrounously is hard for developers to handle their responses. Using these new methods could be easier to take asynchrounous functions sequentially like accessing synchrounous functions.

>Please be aware that Promise.all() does not guarantee all requests in a sequence but for the resolved result; besides, if a process got failed, Promise.all() would only get error catch


```js
// Summary
var p1 = new Promise((resolve, reject) => { 
  setTimeout(() => {
    console.log(`processing one`);
    return resolve('one')
  },4000); 
});
var p2 = new Promise((resolve, reject) => { 
  setTimeout(() => {
    console.log(`processing two`);
    return resolve('two')
  },3000);
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(`processing three`);
    return resolve('three')
  },2000);
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(`processing four`);
    return resolve('four')
  },1000);
});

// error
var p5 = new Promise((resolve, reject) => {
  reject(new Error('reject'));
});


// execute
Promise.all([p1, p2, p3, p4])
.then(values => { 
  console.log(values); // [ 'one', 'two', 'three', 'four' ]
})
.catch(error => { 
  console.error(error.message) // if run with p5
});

//processing four
//processing three
//processing two
//processing one
```
# Reference
http://blog.kueiapp.com/en/programming/understand-promise-in-5-minutes-javascript/