Promise定义及应用

    定义:Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。(用来处理异步事件的对象)

    为什么要用?

    可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

    使代码更加具有可读性和可维护性,将数据请求与数据处理明确的区分开来,此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。

    Promise 对象有以下两个特点:

    1. Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)

    只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。

    2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。

    只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。

    这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

例:

    function fn(num) {
      return new Promise(function (resolve, reject) {
        if (typeof num == 'number') {
          resolve();
        } else {
          reject();
        }
      }).then(function () {
        console.log('参数是一个number值');
      }, function () {
        console.log('参数不是一个number值');
      })
    }
    fn('hahha');
    fn(1234);
    //执行到resolve(),则对应执行到then方法里,两者之前可以传参
    // ========
    var fn = function (num) {
      return new Promise(function (resolve, reject) {
        if (typeof num == 'number') {
          resolve(num);
        } else {
          reject('TypeError');
        }
      })
    }
    fn(2).then(function (num) {
      console.log('first: ' + num);
      return num + 1;
    })
      .then(function (num) {
        console.log('second: ' + num);
        return num + 1;
      })
      .then(function (num) {
        console.log('third: ' + num);
        return num + 1;
      });
    //promise最常用的用法,通过链式的写法,去维护多个异步操作的依赖关系,
    // 因为.then()后也返回一个promise对象,所以可以继续用then(),
    // 而且上一个then return后的值会传到下个then的参数里,这样就具备了执行下一个异步操作的前提条件。   
    // ========
    var logging = document.getElementById('test-promise2-log');
    while (logging.children.length > 1) {
      logging.removeChild(logging.children[logging.children.length - 1]);
    }
    function log(s) {
      var p = document.createElement('p');
      p.innerHTML = s;
      logging.appendChild(p);
    }
    // 0.5秒后返回input*input的计算结果:
    function multiply(input) {
      return new Promise(function (resolve, reject) {
        log('calculating ' + input + ' x ' + input + '...')
        setTimeout(resolve, 500, input * input);
      });
    }
    // 0.5秒后返回input+input的计算结果:
    function add(input) {
      return new Promise(function (resolve, reject) {
        log('calculating ' + input + ' + ' + input + '...');
        setTimeout(resolve, 500, input + input);
      });
    }
    var p = new Promise(function (resolve, reject) {
      log('start new Promise...');
      resolve(123);
    });
    p.then(multiply)
      .then(add)
      .then(multiply)
      .then(add)
      .then(function (result) {
        log('Got value: ' + result);
      });
    // setTimeout方法的第三个参数会往第一个参数(函数)传参
    // multiply,add都是一个promise对象,所以会接受参数传值,
    // 然后通过resolve(成功后执行的方法,之前会通常会处理数据),
    // 把参数值传给,promise对象(multiply,add)then方法里的参数上,
    // 就这样实现了promise对象then的链式写法,也就实现了多个异步操作(有前后依赖关系)的链式写法
    // ========
    // ajax函数将返回Promise对象:
    function ajax(method, url, data) {
      var request = new XMLHttpRequest();
      return new Promise(function (resolve, reject) {
        request.onreadystatechange = function () {
          if (request.readyState === 4) {
            if (request.status === 200) {
              resolve(request.responseText);
            } else {
              reject(request.status);
            }
          }
        };
        request.open(method, url);
        request.send(data);
      });
    }
    var logCon = document.getElementById('test-promise2-log');
    var pajax = ajax('GET', '/api/categories');
    pajax.then(function (text) { // 如果AJAX成功,获得响应内容
      logCon.innerText = text;
    }).catch(function (status) { // 如果AJAX失败,获得响应代码
      logCon.innerText = 'ERROR: ' + status;
    });
    // ========
    var p1 = new Promise(function (resolve, reject) {
      setTimeout(resolve, 500, 'P1');
    });
    var p2 = new Promise(function (resolve, reject) {
      setTimeout(resolve, 600, 'P2');
    });
    // 同时执行p1和p2,并在它们都完成后执行then:
    Promise.all([p1, p2]).then(function (results) {
      console.log(results); // 获得一个Array: ['P1', 'P2']
    });
    //有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的                
    //结果即可。这种情况下,用Promise.race()实现
    var p1 = new Promise(function (resolve, reject) {
        setTimeout(resolve, 500, 'P1');
    });
    var p2 = new Promise(function (resolve, reject) {
        setTimeout(resolve, 600, 'P2');
    });
    Promise.race([p1, p2]).then(function (result) {
        console.log(result); // 'P1'
    });

猜你喜欢

转载自blog.csdn.net/qq_41111677/article/details/109855758