# Promise

* Represents an action that hasn't yet completed
* solution to callback hell

```javascript
var myPromise = new Promise(function(resolve, reject){
    var itemRequested = 10;

    if(itemRequested === 10 ){
        resolve("Happy to offer you 100 Rs.");
    }

    if(itemRequested === 'star'){
        reject("It's false hope");
    }
});

myPromise.then(function(res){
    console.log(res)
}, function(res){
    console.log(res)
})
```

## Promise Chaining

```javascript
myPromise.then(function(res){
    return res;
}, function(err){
    return err;
})
.then(function(res){
    console.log(res + "Cool buddy"); // Happy to offer you 100 Rs.Cool buddy
});
```

## catch

The catch callback is executed when the promise is rejected

```javascript
new Promise(function(resolve, reject) {
    // A mock async action using setTimeout
    setTimeout(function() { reject('Done!'); }, 3000);
})
.then(function(e) { console.log('done', e); })
.catch(function(e) { console.log('catch: ', e); });

// From the console:
// 'catch: Done!'
```

## Promise.all

```javascript
Promise.all([promise1, promise2]).then(function(results) {
    // Both promises resolved
})
.catch(function(error) {
    // One or more promises was rejected
});
```

## Promise.all demo

```javascript
Promise.all([fetch('/users.json'), navigator.getBattery()]).then(function(results) {
    // Both promises done!
});
```

## If any promise is rejected the catch fires for the first rejection:

```javascript
var promise1 = new Promise(function(resolve, reject) { 
    setTimeout(function() { resolve('First!'); }, 4000);
});

var promise2 = new Promise(function(resolve, reject) { 
    setTimeout(function() { reject('Second!'); }, 3000);
});

Promise.all([promise1, promise2]).then(function(results) {
    console.log('Then: ', one);
}).catch(function(err) {
    console.log('Catch: ', err);
});

// output
// Catch: Second!
```

## Promise.all demo

```javascript
var posts = fetch('https://reqres.in/api/posts');
var users = fetch('https://reqres.in/api/users');


Promise.all([posts, users])
    .then((res) => {
    return Promise.all(res.map(r => r.json()));
})
.then(res => {
      let [posts, users ] = res;
    console.log(posts);    
      console.log(users);

})
.catch(err => {
    console.log(err);
})
```

## Promise.race

Triggers as soon as any promise is resolved

```javascript
var promise1 = new Promise(function(resolve, reject) { 
    setTimeout(function() { resolve('First!'); }, 4000);
});

var promise2 = new Promise(function(resolve, reject) { 
    setTimeout(function() { resolve('Second!'); }, 3000);
});

Promise.all([promise1, promise2]).then(function(results) {
    console.log('Then: ', one);
}).catch(function(err) {
    console.log('Catch: ', err);
});

// output
// Then: Second!
```

## Ex - Native xhr request

```javascript
var ajax = function(url){
    return new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest();

        xhr.onreadystatechange = function(){
            if(xhr.readyState ===  4 ){
                if(xhr.status === 200){
                    resolve(xhr.responseText);
                } else {
                    reject("something gone wrong");
                }
            }
        };

        xhr.open('get', url, true);
        xhr.send();
    });

};

ajax('https://api.github.com/users/hesing').then(function(res){
    console.log(res)
}, function(err){
    console.log(err)
});
```

## fetch api return promise

```javascript
fetch('/some/url')
    .then(function(response) {
        return //...
    }).then(function(returnedValue) {
        // ...
    }).catch(function(err) {
        // Error 
    });
```

* [Battery API](https://davidwalsh.name/javascript-battery-api) return promise
* [fetch API](https://davidwalsh.name/fetch)  return promise
