Six features of the Promise pattern for JavaScript asynchronous programming

  • 2020-03-30 02:31:24
  • OfStack

Before we get started, we'd like to take a look at what Javascript Promise looks like:


var p = new Promise(function(resolve, reject) {
  resolve("hello world");
});

p.then(function(str) {
  alert(str);
});

1. Then () returns a Forked Promise

What's the difference between the following two pieces of code?


// Exhibit A
var p = new Promise();
p.then(func1);
p.then(func2);

// Exhibit B
var p = new Promise();
p.then(func1)
.then(func2);

If you're serious, Promises is nothing more than an array of one-dimensional callbacks. However, this is not the case. Each then() call returns a forked promise. So, in ExhibitA, if func1() throws an exception, func2() is still called normally.

In ExhibitB, if func1() throws an error, fun2() will not be called because the first call returns a new promise, which is rejected in func1(). The result is that func2() is skipped.

Summary: promises can be forked into multiple paths, similar to a complex flowchart.

2. Callback should deliver the results

When do you get a warning when you run the following code?


var p = new Promise(function(resolve, reject) {
  resolve("hello world");
});

p.then(function(str) {})
.then(function(str) {
  alert(str);
});

The alert in the second then() shows nothing. This is because the callback function, in the context of the promise, because the change in the result does not have a callback function. Promise expects your callback function to return the same result or a replacement result, which is then passed to the next callback function.

Similar to the use of adpater to change the results, as follows:


var feetToMetres = function(ft) { return ft*12*0.0254 };

var p = new Promise();

p.then(feetToMetres)
.then(function(metres) {
  alert(metres);
}); 

3. Only exceptions from the previous layer can be caught

What's the difference between the two pieces of code?


// Exhibit A
new Promise(function(resolve, reject) {
  resolve("hello world");
})
.then(
  function(str) {
    throw new Error("uh oh");
  },
  undefined
)
.then(
  undefined,
  function(error) {
    alert(error);
  }
);
 
// Exhibit B
new Promise(function(resolve, reject) {
  resolve("hello world");
})
.then(
  function(str) {
    throw new Error("uh oh");
  },
  function(error) {
    alert(error);
  }
);

In the first code, the exception thrown in the first then() will be caught by the second then(), and the "uh oh" warning will be triggered. The exception that follows only the previous level is caught.

In the second piece of code, the callback function and the error callback function are at the same level, meaning that when an exception is thrown in a callback, it will not be caught. In fact, the error callback in the second code will only be thrown if the promise is in a reject state or if the promise itself fails

Errors can be recovered

In an error callback function, if you do not rethrow the error, promise assumes that you have recovered from the error and reverted to the resolved state. In the next example, "I'm saved" will be displayed because the error callback in the first then() did not rethrow the exception.


var p = new Promise(function(resolve, reject) {
  reject(new Error("pebkac"));
});

p.then(
  undefined,
  function(error) { }
)
.then(
  function(str) {
    alert("I am saved!");
  },
  function(error) {
    alert("Bad computer!");
  }
);

Promise can be thought of as a level on an onion. Each then() adds another layer to the onion. Each level represents an activity being processed. When the level ends, the result is considered fixed and ready for the next level.

5. Promises can be suspended

6. It will not be implemented immediately

Will you get a prompt if you run the following code?


function runme() {
  var i = 0;

  new Promise(function(resolve) {
    resolve();
  })
  .then(function() {
    i += 2;
  });
  alert(i);
}

Because the promise is immediately parsed and the then() method is immediately executed, you might think that hint 2 would be elicited. But the promise definition requires that all calls be forced to be asynchronous. So the prompt is generated before it is modified.


Related articles: