promise的基本用法

```clike
```handlebars
```handlebars
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    //ES6规定,Promise对象是一个构造函数,用来生成Promise实例
     /* 
      Promise构造函数接受一个函数作为参数,
      该函数的两个参数分别是resolve和reject. 
      它们是两个函数,由JavaScript引擎提供,不用自己部署.
      resolve函数的作用是,将Promise对象的状态从 "未完成" 变为 "成功"
      (即从pending变为rejected),在异步操作失败时调用,
      并将异步操作报出的错误,作为参数传递出去
    */
    // const romise = new Promise(function(resolve,reject){
    //   //...some code
    //   if ('/* 异步操作成功 */'){
    //     resolve(value);
    //   } else{
    //     reject(error);
    //   }
    // })

    /* 
      Promise实例生成以后,
      可以用then方法分别指定resolved状态和rejected状态的回调函数。
      then方法可以接受两个回调函数作为参数,
      第一个回调函数是Promise对象的状态变为resolve时调用,
      第二个回调函数是Promise对象的状态变为rejected时调用。
      这两个函数都是可选的,不一定要提供。它们都接受Promise对象传出的值作为参数
    */
  //  Promise.then(
  //    function(value){
  //     //success
  //   },
  //   function(error){
  //     //failuer
  //   }
  //  );

   //eg:
   function timeout(ms) {
     return new Promise((resolve,reject) => {
       setTimeout(resolve,ms,'done');
     });
    }
    timeout(100).then((value) =>{
      console.log(value)
    });
    /* 
      上述代码中,timeout方法返回一个Promise实例,
      表示一段时间以后才会发生的结果,
      过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,
      就会触发then方法绑定的回调函数
    */
   
    //Promise新建后就会立即执行
    let promise = new Promise(function(resolve,reject){
      console.log('Promise');
      resolve();
    })
    promise.then(function(){
      console.log('resolved.');
    });
    console.log('Hi!!!!!');
    //Promise
    //Hi!!!!
    //resolved
    /* 
      上述代码中,Promise新建后立即执行,所以首先输出的时Promise. 
      然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,
      所以resolved最后输出
    */

    //eg:异步加载图片
    function loadImageAsync(url){
      return new Promise(function(resolve,reject) {
        const image =new Image();
        image.onload = function() {
          resolve(image);
        };
        image.onerror = function() {
          reject(new Error('Could not load image at ' +url));
        };
        image.src = url;
      });
    }
    /* 
      上述代码中,使用Promise包装了一个图片加载的异步操作,
      如果加载成功,就调用resolve方法,否则就调用reject方法
    */

    //eg:用Promise对象实现的Ajax操作的例子:
    // const getJSON = function(url) {
    //   const promise = new Promise(function(resolve,reject){
    //     const handler = function() {
    //       if (this.readyState !==4) {
    //         return;
    //       }
    //       if (this.status ==200){
    //         resolve(this.response);
    //       } else {
    //         reject(new Error(this.statusText));
    //       }
    //     };
    //     const client = new XMLHttpRequest();
    //     client.open('GET',url);
    //     client.onreadystatechange = handler;
    //     client.responseType = 'json';
    //     client.setRequestHeader("Accept","application/json");
    //     client.send();
    //   });
    //   return promise;
    // };
    // getJSON("/posts.json").then(function(json){
    //   console.log('Contents:'+json);
    // },function(error){
    //   console.error('出错了',error);
    // });
    /* 
      上述代码中,getJSON是对XMLHttpRequest对象的封装,
      用于发出一个针对JSON数据的http请求,并且返回一个Promise对象。
      需要注意的是,在getJSON内部,resolve函数和reject函数调用时,都带有参数。
      如果调用resolve函数和reject函数时1带有参数,那么它们的参数会被传递给回调函数。
      reject的回调函数通常是error对象的实例,表示抛出的错误,
      resolve函数的参数除了正常的值以外,还可能是另一个promise实例,eg:
    */
   const p1 = new Promise(function(resolve,reject) {
     //....
   });

   const p2 = new Promise(function (resolve,reject){
     //...
     resolve(p1);
   })
      /* 
        上述代码中,p1和p2都是Promise的实例,
        但是p2的resolve方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作。
        注意,这时p1的状态就会传递给p2,也就是说p1的状态决定了p2的状态。
        如果p1的状态是pending,那么p2的回调函数就会等待p1的状态改变;
        如果p1的状态已经是resolved或者是rejected,那么p2的回调函数将会立即执行
      */



    //  const p1 = new Promise(function(resolve,reject) {
    //  setTimeout(() => reject(new Error('fail')),3000)
    //  })

    //   const p2 = new Promise(function (resolve,reject) {
    //   setTimeout(() => resolve(p1),1000)
    //   })

    //   p2
    //     .then(result => console.log(result))
    //     .catch(error => console.log(error))
      //输出结果    Error:fail
      /* 
        上述代码中,p1是一个Promise,3秒之后变为rejected。
        p2的状态在1秒之后改变,resolve方法返回的是p1。
        由于p2返回的是另一个promise,导致p2自己的状态无效了,由p1的额状态决定p2的状态。
        所以,后面的then语句都变成针对后者(p1).
        又过了2秒,p1变为rejectd,导致触发catch方法指定的回调函数
        注意:调用resolve或reject并不会终结Promise的参数函数的执行
      */


      new Promise((resolve,reject) => {
        resolve(1);
        console.log(2);
      }).then (r => {
        console.log(r);
      });
      //2
      //1
      /* 
        上述代码中,调用resolve(1)以后,后面的console.log(2)还是会执行,并且会首先打印出来。
        这是因为立即resolved的Promise是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
        一般来说,调用resolve或reject后,Promise的使命就完成了,后续操作应该放在then方法里面,
        而不应该直接写在resolve或者reject的后面。
        所以,最好在它们前面加上return语句,这样就不会有意外。
      */
      new Promise((resolve, reject) => {
      return resolve(1);
     // 后面的语句不会执行
      console.log(2);
})


  </script>
</body>
</html>


猜你喜欢