29

I am trying to wrap my head around promise object in JavaScript. So here I have this little piece of code. I have a promise object and two console.log() on either side of the promise object. I thought it would print

hi

There!

zami

but it printed

hi

zami

There!

Why it is like that? I have zero understanding on how promise works, but I understand how asynchronous callback works in JavaScript. Can any one shed some light on this topic?

console.log('hi');
var myPromise = new Promise(function (resolve, reject) {
    if (true) {
        resolve('There!');
    } else {
        reject('Aww, didn\'t work.');
    }
});

myPromise.then(function (result) {
    // Resolve callback.
    console.log(result); 
}, function (result) {
    // Reject callback.
    console.error(result);
});
console.log('zami');
Luu Bieu Nghi
  • 21
  • 1
  • 6
AL-zami
  • 8,902
  • 15
  • 71
  • 130
  • 1
    If you have experience with asynchronous callbacks, you should recognise the pattern: the onfulfill and onreject callbacks passed to `.then(…)` are called asynchronously. – Bergi Dec 05 '19 at 09:28

9 Answers9

29

Summary:

A promise in Javascript is an object which represent the eventual completion or failure of an asynchronous operation. Promises represent a proxy for a value which are getting in some point in the future.

A promise can have 3 states which are the following:

  1. Pending: This is the initial state of the promise, the promise is now waiting for either to be resolved or rejected. For example, when are reaching out to the web with an AJAX request and wrapping the request in a promise. Then the promise will be pending in the time window in which the request is not returned.
  2. Fulfilled: When the operation is completed succesfully, the promise is fulfilled. For example, when we are reaching out to be web using AJAX for some JSON data and wrapping it in a promise. When we are succesfully getting data back the promise is said to be fulfilled.
  3. Rejected: When the operation has failed, the promise is rejected. For example, when we are reaching out to be web using AJAX for some JSON data and wrapping it in a promise. When we are getting a 404 error the promise has been rejected.

Promise Constructor:

We can create a promise in the following manner:

let prom = new Promise((res, rej) => {
  console.log('synchronously executed');
  if (Math.random() > 0.5) {
    res('Success');
  } else {
    rej('Error');
  }
})


prom.then((val) => {
  console.log('asynchronously executed: ' + val);
}).catch((err) => {
  console.log('asynchronously executed: ' + err);
}).finally(() => {
  console.log('promise done executing');
});


console.log('last log');

Points of interest:

  • The code inside the promise constructor is synchronously executed.
  • then method takes as a first argument a callback which is asynchronously executed on promise fulfillment.
  • then method takes as a second argument a callback which is asynchronously executed on promise rejection. However we are usually using the catch method for this (because this is more verbose), which also takes a callback which is asynchronously executed on promise rejection. catch is essentially the same as then(null, failCallback).
  • The then callback receives as a first argument the resolved value (the string 'success' in this case).
  • The catch callback receives as a first argument the rejected value (the string 'Error' in this case).
  • The finally method receives a callback which is executed on both promise fulfillment and rejection. Here we can write 'cleanup' code which need to be executed always regardless of promise outcome.

Your example:

In your code 'Zami' was printed before 'there' because the log which logged 'there' was in a then callback function. We earlier pointed out that these callbacks are executed asynchronously and thus will be executed last.

Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155
21

Promise execution is asynchronous, which means that it's executed, but the program won't wait until it's finished to continue with the rest of the code.

Basically, your code is doing the following:

  1. Log 'Hi'
  2. Create a promise
  3. Execute the promise
  4. Log 'zami'
  5. Promise is resolved and logs 'There'.

If you want it to print 'Hi there, zami', you will have to

myPromise.then(function (result) {
    // Resolve callback.
    console.log(result); 
    console.log('zami');
}, function (result) {
    // Reject callback.
    console.error(result);
});
Alberto Rivera
  • 3,652
  • 3
  • 19
  • 33
  • 1
    so it is asynchronous like other web apis like setTimeout,ajax call etc.Any code inside pormise object will be asynchronous? – AL-zami Sep 12 '16 at 20:29
  • 1
    Yeah, promises function very similarly to setTimeout. You can actually make promises from setTimeout as demonstrated here http://stackoverflow.com/questions/34255351/is-there-a-version-of-settimeout-that-returns-an-es6-promise – Alberto Rivera Sep 12 '16 at 20:32
  • in some example i see writers wrote ajax code inside promise object.AJAX i s asynchronous by default.Why use it inside promises? – AL-zami Sep 12 '16 at 20:34
  • Can you write one of those examples? – Alberto Rivera Sep 12 '16 at 20:35
  • you will find it under this article...http://code.tutsplus.com/tutorials/keeping-promises-with-javascript--cms-25056 – AL-zami Sep 12 '16 at 20:36
  • I am guessing to simplify the workflow. After wrapping the ajax code in a promise, you can be sure that the promise will be resolved if everything went well, and that it will fail if something bad happened. Afterwards, you can handle the errors/data easily. – Alberto Rivera Sep 12 '16 at 20:42
  • Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – GunasekaranR Nov 16 '18 at 12:31
  • This is simply wrong. Promises block. You only think they don't because you have called non-blocking library functions from within them. Put a tight loop inside a promise that has a long delay. You will see that the Promise is blocking. You can also see this by single stepping through the code. When you get to the new Promise line, hit step in, and you will see execution flowing into the promise. I agree with posters observation what Promises do is to help organize callbacks. That is a good thing, but it isn't 'non-blocking'. –  Jul 14 '19 at 16:51
6

Even though you resolved the promised synchronously, the handlers you pass into then get called asynchronously. This is according to the defined specification:

onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack

Aaronius
  • 4,936
  • 6
  • 31
  • 40
6

I would recommend you to understand how event loop works in JavaScript.

take time and watch this Video.

It will clear your doubts. enter image description here

UniCoder
  • 3,005
  • 27
  • 26
0

A Promise is an object representing the eventual completion or failure of an asynchronous operation.

Below is the example of promise:

const post = new Promise((resolve, reject) => {
    resolve("Appended from getPostWithPromise()");
});

const getPostWithPromise = function () {
    post
    .then(function (fulfilled) {
        $("body").append("<div>" + fulfilled + "</div>");
    })
    .catch(function (error) {
        console.log(error);
    });
}

function getPostWithoutPromise() {
    $("body").append("<div>Appended from getPostWithoutPromise()</div>");
}

$(function () {
    getPostWithPromise(); // this will print last
    getPostWithoutPromise(); // this will print first
    $("body").append("<div>Appended directly</div>"); // second
});

you can test it => JavaScript Promises example

for detail understanding you can read this post => https://scotch.io/tutorials/javascript-promises-for-dummies

Hamza Iftikhar
  • 584
  • 6
  • 18
0

Promise:

new Promise((resolve, reject) => {
        resolve(whateverObject)
        reject(whateverErrorObject)
})
  • It is just object that can be chained with then()
  • You also can make promise! you can return whatever object in that success parameter (resolve) and error parameter (reject)

so very simple concept bro!

Jetwiz
  • 642
  • 7
  • 14
0
  1. Promises are objects.
  2. Each promise object has a then method.
  3. The then method of the promise object accepts a function as a first parameter.
  4. If we call the then method of a promise, the callback function will be executed once the promise gets resolved.

Flow of execution

const promiseObj = new Promise((res, rej) => {
  console.log("Promise constructor are synchronously executed");
  res("Hii Developer");
})

const callbackFunction = (resolvedValue) => console.log("Resolved Value ", resolvedValue);


promiseObj.then(callbackFunction);

console.log("I am the executed after the constructor");

In the above example, we have created a promise object using the Promise constructor. The constructor function is synchronously executed.

After creating the promise object, we are calling the then method of the promise object. We have passed a callback function in the first argument of the then method. This callback function will be executed once the promise gets resolved and the stack of the js engine gets empty.

Himanshu
  • 71
  • 3
0

Promise is a object that represents the completion or failure of a event . Promise is a asynchronous thing in JS which means that it's executed, but the program won't wait until it's finished to continue with the rest of the code. So it wont be executed simultaneously. It would take time to either complete or fail for a given task and then execution.

In your Case

  1. log'Hi'.
  2. First your mypromise variable will store a promise object i.e either rejected or resolved(for this, it would take time)
  3. But JS engine will execute further code first then the asynchronous task. SO u will get 'zami'.
  4. once the promise resolved or rejected. It will be called or used wherever it is used in the code. In this case ,it is resolved and log 'there!' in console.
-1

let prom = new Promise((res, rej) => {
  console.log('synchronously executed');
  if (Math.random() > 0.5) {
    res('Success');
  } else {
    rej('Error');
  }
})


prom.then((val) => {
  console.log('asynchronously executed: ' + val);
}).catch((err) => {
  console.log('asynchronously executed: ' + err);
}).finally(() => {
  console.log('promise done executing');
});


console.log('last log');