Promise解析

1、一个简单的Promise的例子:生成一个0~2之间的数字,如果值小于1,则等待一段时间后返回成功,否则返回失败

function test(resolve,reject){
    var timeOut = Math.random() * 2;
    console.log('set time out to '+timeOut+' seconds.');
    setTimeout(function(){
      if(timeOut < 1){
        console.log('success');
        resolve('200 ok'); //不需要return
      }else {
        console.log('call reject');
        reject('timeout in '+timeOut+' seconds');
      }
    },timeOut*1000)
  }

//调用
var p1 = new Promise(test);
  var p2 = p1.then(function(result){
    console.log('成功:'+result);
  });
  var p3 = p2.catch(function(reason){
    console.log('失败:'+reason);
  });

以上调用也可以综合起来写:

new Promise(test).then(function(result){
    console.log('成功:'+result);
  }).catch(function(reason){
    console.log('失败:'+reason);
  });
也可以写成如下形式:
new Promise(function(resolve,reject){
    var timeOut = Math.random() * 2;
    console.log('set time out to '+timeOut+' seconds.');
    setTimeout(function(){
      if(timeOut < 1){
        console.log('success');
        resolve('200 ok');
      }else {
        console.log('call reject');
        reject('timeout in '+timeOut+' seconds');
      }
    },timeOut*1000)
  }).then(function(result){
    console.log('成功:'+result);
  }).catch(function(reason){
    console.log('失败:'+reason);
  });
2、多个Promise的串行操作示例
function multiply(input) {
    return new Promise(function(resolve,reject) {
      console.log('calculate '+input+'*'+input+': ');
      setTimeout(resolve,0.5*1000,input*input);
    });
  }

  function add(input) {
    return new Promise(function(resolve,reject) {
      console.log('calculate '+input+'+'+input+': ');
      setTimeout(resolve, 0.5*1000, input+input);
    })
  }

  var p = new Promise(function(resolve, reject) {
    console.log('start new Promise');
    resolve(2);
  });

  p.then(multiply).then(add).then(function(result) {  //then中可以直接使用promise对象?
    console.log('get result='+result);
  }).catch(function(reason) {
    console.log('error')
  });
3、使用Promise实现一个ajax

一般创建ajax的过程:

(1)创建‘XMLHttpRequest’对象,也就是创建一个异步调用对象;

(2)创建一个新的‘HTTP’请求,并指定该‘HTTP’请求的方法、‘URL、以及验证信息;

(3)设置响应‘HTTP’请求状态变化的函数;

(4)发送‘HTTP’请求;

(5)获取异步调用返回的数据;

(6)使用JavaScript和DOM实现局部刷新。

function ajax(method, url, data) {
    var xhr = new XMLHttpRequest();
    xhr.open(method, url,true);
    xhr.onreadystatechange = function(){
      if(xhr.readyState === 4){
        if(xhr.status === 200) {
          console.log('success')  
        }
      }
    }
    xhr.send(data);
  }

//调用
  ajax('GET','index.json',{});

用Promise实现ajax的创建过程

function ajaxP(method, url, data) {
    var xhr = new XMLHttpRequest();
    return new Promise(function(resolve, rejset){
      xhr.onreadystatechange = function() {
        if(xhr.readyState === 4) {
          if(xhr.status === 200) {
            resolve(xhr.responseText);
          }else {
            reject(xhr.status);
          }
        }
      };
      xhr.open(method, url,true);
      xhr.send(data);
    });
  }

//调用
  var p = ajaxP('GET','index.json',{});
  p.then(function(result) {
    console.log(result);
  }).catch(function(reason) {
    console.log(reason);
  });

4、除了串行执行若干异步任务外,Promise还可以并行执行异步任务。
试想一个页面聊天系统,我们需要从两个不同的URL分别获得用户的个人信息和好友列表,这两个任务是可以并行执行的,用Promise.all()实现如下:

var pa1 = new Promise(function(resolve, reject) {
    console.log('pa1');
    setTimeout(resolve, 500, 'pa1');
  });
  var pa2 = new Promise(function(resolve, reject) {
    console.log('pa2');
    setTimeout(resolve, 3000, 'pa2');
  });
  // 同时执行p1和p2,并在它们都完成后执行then:
  Promise.all([pa1,pa2]).then(function(result) {
    console.log(result); // 获得一个Array: ['P1', 'P2']
  });

5、有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。这种情况下,用Promise.race()实现:

var pr1 = new Promise(function(resolve, reject) {
    console.log('pr1');
    setTimeout(resolve, 500, 'pr1');
  });
  var pr2 = new Promise(function(resolve, reject) {
    console.log('pr2');
    setTimeout(resolve, 600, 'pr2');
  });
  Promise.race([pr1,pr2]).then(function(result) {
    console.log(result); // 'P1'
  });

以上部分参考文章:

廖雪峰的Promise讲解

大白话讲解Promise


猜你喜欢

转载自blog.csdn.net/zhouyy919/article/details/80043972