Home >Web Front-end >JS Tutorial >Detailed explanation of Promise usage in ES6

Detailed explanation of Promise usage in ES6

php中世界最好的语言
php中世界最好的语言Original
2018-05-31 10:27:171203browse

This time I will bring you a detailed explanation of the use of Promise in ES6. What are the precautions for using Promise in ES6? The following is a practical case, let's take a look.

Of course, this does not mean that it has burst into a full stack. The skills of the whole stack are very concentrated, not only the front-end can write some HTML and some interactions, but the back-end is familiar with the addition, deletion, checking and modification of the database.

Everyone who has come into contact with Node must know that Node is famous for its asynchronous (Async) callbacks. Its asynchronicity improves the execution efficiency of the program, but it also reduces the readability of the program. If we have several asynchronous operations, and the latter operation requires the data returned by the previous operation to be executed, then according to the general execution rules of Node, orderly asynchronous operations are usually nested layer by layer.

In order to solve this problem, ES6 proposed the implementation of Promise.

Meaning

Promise

ObjectUsed for the final completion (or failure) of an asynchronous operation and its result value express. To put it simply, it is used to process asynchronous operations. If the asynchronous processing is successful, the successful operation will be executed. If the asynchronous processing fails, the error will be captured or subsequent operations will be stopped.

Its general representation is:

new Promise(
  /* executor */
  function(resolve, reject) {
    if (/* success */) {
      // ...执行代码
      resolve();
    } else { /* fail */
      // ...执行代码
      reject();
    }
  }
);
Among them, the parameter executor in Promise is an executor function, which has two parameters, resolve and reject. There are usually some asynchronous operations inside it. If the asynchronous operation is successful, you can call resolve() to set the

status of the instance to fulfilled, that is, completed. If it fails, you can call reject() to Set the status of the instance to rejected, that is, failed.

We can think of the Promise object as a factory assembly line. For the assembly line, from the perspective of its job functions, it has only three states, one is the initial state (when it is just turned on), and the other is One is that the processed product is successful, and the other is that the processed product fails (some failure occurred). Similarly for the Promise object, it also has three states:

  1. pending: The initial state, also called the undecided state, is the state after calling the executor executor function when initializing the Promise.

  2. fulfilled: completion status, which means the asynchronous operation was successful.

  3. rejected: Failure status means that the asynchronous operation failed.

It has only two states that can be converted, namely

  1. The operation is successful: pending -> fulfilled

  2. Operation failed: pending -> rejected

And this state transformation is one-way and irreversible. The determined state (fulfilled/rejected) cannot be transferred back to the initial state ( pending).

Method

Promise.prototype.then()

The Promise object contains the then method, Then() returns a Promise object after being called, which means that the instantiated Promise object can be called in a chain, and this then() method can receive two functions, one is the function after successful processing, and the other is the error result. function.

As follows:

var promise1 = new Promise(function(resolve, reject) {
 // 2秒后置为接收状态
 setTimeout(function() {
  resolve('success');
 }, 2000);
});
promise1.then(function(data) {
 console.log(data); // success
}, function(err) {
 console.log(err); // 不执行
}).then(function(data) {
 // 上一步的then()方法没有返回值
 console.log('链式调用:' + data); // 链式调用:undefined 
}).then(function(data) {
 // ....
});
Here we mainly focus on the status of the Promise object returned after the promise1.then() method is called. Is it pending, fulfilled, or rejected?

The status of the returned Promise object is mainly based on the value returned by the promise1.then() method, which is roughly divided into the following situations:

  1. If a parameter is returned in the then() method value, then the returned Promise will become the receiving state.

  2. If an exception is thrown in the then() method, the returned Promise will become rejected.

  3. If the then() method calls the resolve() method, the returned Promise will become the receiving state.

  4. If the then() method calls the reject() method, the returned Promise will become rejected.

  5. If the then() method returns a new Promise instance with an unknown state (pending), then the new Promise returned is in an unknown state.

  6. If the then() method does not explicitly specify resolve(data)/reject(data)/return data, then the new Promise returned is the receiving state, which can be performed layer by layer Pass it down.

Conversion examples are as follows:

var promise2 = new Promise(function(resolve, reject) {
 // 2秒后置为接收状态
 setTimeout(function() {
  resolve('success');
 }, 2000);
});
promise2
 .then(function(data) {
  // 上一个then()调用了resolve,置为fulfilled态
  console.log('第一个then');
  console.log(data);
  return '2';
 })
 .then(function(data) {
  // 此时这里的状态也是fulfilled, 因为上一步返回了2
  console.log('第二个then');
  console.log(data); // 2
  return new Promise(function(resolve, reject) {
   reject('把状态置为rejected error'); // 返回一个rejected的Promise实例
  });
 }, function(err) {
  // error
 })
 .then(function(data) {
  /* 这里不运行 */
  console.log('第三个then');
  console.log(data);
  // ....
 }, function(err) {
  // error回调
  // 此时这里的状态也是fulfilled, 因为上一步使用了reject()来返回值
  console.log('出错:' + err); // 出错:把状态置为rejected error
 })
 .then(function(data) {
  // 没有明确指定返回值,默认返回fulfilled
  console.log('这里是fulfilled态');
});

Promise.prototype.catch()

catch()方法和then()方法一样,都会返回一个新的Promise对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略then()方法的第二个参数,把错误处理控制权转交给其后面的catch()函数,如下:

var promise3 = new Promise(function(resolve, reject) {
 setTimeout(function() {
  reject('reject');
 }, 2000);
});
promise3.then(function(data) {
 console.log('这里是fulfilled状态'); // 这里不会触发
 // ...
}).catch(function(err) {
 // 最后的catch()方法可以捕获在这一条Promise链上的异常
 console.log('出错:' + err); // 出错:reject
});

Promise.all()

Promise.all()接收一个参数,它必须是可以迭代的,比如数组

它通常用来处理一些并发的异步操作,即它们的结果互不干扰,但是又需要异步执行。它最终只有两种状态:成功或者失败。

它的状态受参数内各个值的状态影响,即里面状态全部为fulfilled时,它才会变成fulfilled,否则变成rejected。

成功调用后返回一个数组,数组的值是有序的,即按照传入参数的数组的值操作后返回的结果。如下:

// 置为fulfilled状态的情况
var arr = [1, 2, 3];
var promises = arr.map(function(e) {
 return new Promise(function(resolve, reject) {
  resolve(e * 5);
 });
});
Promise.all(promises).then(function(data) {
  // 有序输出
 console.log(data); // [5, 10, 15]
 console.log(arr); // [1, 2, 3]
});
// 置为rejected状态的情况
var arr = [1, 2, 3];
var promises2 = arr.map(function(e) {
 return new Promise(function(resolve, reject) {
  if (e === 3) {
   reject('rejected');
  }
  resolve(e * 5);
 });
});
Promise.all(promises2).then(function(data) {
 // 这里不会执行
 console.log(data);
 console.log(arr);
}).catch(function(err) {
 console.log(err); // rejected
});

Promise.race()

Promise.race()和Promise.all()类似,都接收一个可以迭代的参数,但是不同之处是Promise.race()的状态变化不是全部受参数内的状态影响,一旦参数内有一个值的状态发生的改变,那么该Promise的状态就是改变的状态。就跟race单词的字面意思一样,谁跑的快谁赢。如下:

var p1 = new Promise(function(resolve, reject) {
 setTimeout(resolve, 300, 'p1 doned');
});
var p2 = new Promise(function(resolve, reject) {
 setTimeout(resolve, 50, 'p2 doned');
});
var p3 = new Promise(function(resolve, reject) {
 setTimeout(reject, 100, 'p3 rejected');
});
Promise.race([p1, p2, p3]).then(function(data) {
 // 显然p2更快,所以状态变成了fulfilled
 // 如果p3更快,那么状态就会变成rejected
 console.log(data); // p2 doned
}).catch(function(err) {
 console.log(err); // 不执行
});

Promise.resolve()

Promise.resolve()接受一个参数值,可以是普通的值,具有then()方法的对象和Promise实例。正常情况下,它返回一个Promise对象,状态为fulfilled。但是,当解析时发生错误时,返回的Promise对象将会置为rejected态。如下:

// 参数为普通值
var p4 = Promise.resolve(5);
p4.then(function(data) {
 console.log(data); // 5
});
// 参数为含有then()方法的对象
var obj = {
 then: function() {
  console.log('obj 里面的then()方法');
 }
};
var p5 = Promise.resolve(obj);
p5.then(function(data) {
 // 这里的值时obj方法里面返回的值
 console.log(data); // obj 里面的then()方法
});
// 参数为Promise实例
var p6 = Promise.resolve(7);
var p7 = Promise.resolve(p6);
p7.then(function(data) {
 // 这里的值时Promise实例返回的值
 console.log(data); // 7
});
// 参数为Promise实例,但参数是rejected态
var p8 = Promise.reject(8);
var p9 = Promise.resolve(p8);
p9.then(function(data) {
 // 这里的值时Promise实例返回的值
 console.log('fulfilled:'+ data); // 不执行
}).catch(function(err) {
 console.log('rejected:' + err); // rejected: 8
});

Promise.reject()

Promise.reject()和Promise.resolve()正好相反,它接收一个参数值reason,即发生异常的原因。此时返回的Promise对象将会置为rejected态。如下:

var p10 = Promise.reject('手动拒绝');
p10.then(function(data) {
 console.log(data); // 这里不会执行,因为是rejected态
}).catch(function(err) {
 console.log(err); // 手动拒绝
}).then(function(data) {
 // 不受上一级影响
 console.log('状态:fulfilled'); // 状态:fulfilled
});

总之,除非Promise.then()方法内部抛出异常或者是明确置为rejected态,否则它返回的Promise的状态都是fulfilled态,即完成态,并且它的状态不受它的上一级的状态的影响。

总结

大概常用的方法就写那么多,剩下的看自己实际需要再去了解。

解决Node回调地狱的不止有Promise,还有Generator和ES7提出的Async实现。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎样使用Vue实现树形视图数据

如何使用JS求得数组的最小公倍数和最大公约数

The above is the detailed content of Detailed explanation of Promise usage in ES6. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn