美文网首页
JavaScript Promise的用法

JavaScript Promise的用法

作者: 楼主楼主 | 来源:发表于2018-05-04 17:45 被阅读0次

    Promise是JavaScript ES6中的一个新特性,用于异步处理。在没有Promise之前,做异步调用通常使用callback函数的方式:

    function callback(data){
      console.log(data);
    }
    function foo(data,callback){
      //模拟延时返回
      setTimeout(callback,2000,data);
    }
    foo('hello!',callback);
    

    执行代码 一段时间后 控制台打印hello!

    通常我们对异步调用的使用会更加复杂,比如异步调用有可能执行成功或者失败,可能存在着嵌套,多个异步调用全部完成后再执行某些代码等等。用上面的方式,这些需求也是可以满足的,但是为了利于代码的易读、复用、标准化等等需求,ES6提供了Promise来完成这些任务。

    一个最简单的Promise例子:生成一个随机数,如果大于0.5则成功,否则失败:

    // 当随机数大于0.5则成功,否则失败
    function foo(resolve, reject){
      var time = Math.random();
      setTimeout(function(){
        if(time<0.5){
          reject(time);
        }else{
          resolve(time);
        }
      },time*1000);
    }
    new Promise(foo)
      .then(result=>console.log('成功'+result))
      .catch(result=>console.log('失败'+result))
    

    可见Promise把执行过程,处理结果,错误处理都分开了。


    当有嵌套执行异步操作,我们需要任何任务失败则不再继续,并执行错误处理函数,Promise也可以让整个流程变得简洁。下面是一个Promise嵌套执行异步操作的例子:

    // 定义被除数对象
    function Dividend(value){
      var that = this;
      this.value = value;
      this.divided = function(divisor){
        console.log('计算 '+that.value+'除以'+divisor+'...')
        return divide(that.value,divisor);
      }
    }
    
    function divide(num,num1){
      return new Promise(function(resolve,reject){
        if(typeof(num) === 'number' && typeof(num1) === 'number'&& num1!==0){
          //通过resolve返回一个Dividend对象
          setTimeout(resolve, 500,new Dividend(num/num1));
        }else{
          setTimeout(reject, 500, '参数不是数字或者除数为0');
        }
      });
    }
    

    运行:

    // 正确的运算
    divide(100,2)
      .then(dividend=>dividend.divided(2))
      .then(dividend=>dividend.divided(2))
      .then(dividend=>dividend.divided(3))
      .then(dividend=>console.log("结果:"+dividend.value))
      .catch(reason=>console.log("错误:"+reason));
    // 错误的运算
    divide(100,2)
      .then(dividend=>dividend.divided(2))
      .then(dividend=>dividend.divided(0))
      .then(dividend=>dividend.divided(3))
      .then(dividend=>console.log("结果:"+dividend.value))
      .catch(reason=>console.log("错误:"+reason));
    
    

    结果:

    // 正确的运算
    计算 50除以2...
    计算 25除以2...
    计算 12.5除以3...
    结果:4.166666666666667
    // 错误的运算
    计算 50除以2...
    计算 25除以0...
    错误:参数不是数字或者除数为0
    

    除了串联执行若干异步任务外,Promise还可以并联执行异步任务。
    并联执行的逻辑分为两种

    1. 当所有Promise执行完毕后执行任务
    2. 当任意一个Promise执行完毕后执行任务
    // 当所有Promise执行完毕后执行任务
    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) {
        // 获得一个Array: ['P1', 'P2'],结果的顺序和all函数中Promise的顺序一致
        console.log(results); });
    
    //当任意一个Promise执行完毕后执行任务
    var p1 = new Promise(function (resolve, reject) {
        setTimeout(resolve, 500, 'P1');
    });
    var p2 = new Promise(function (resolve, reject) {
        setTimeout(resolve, 600, 'P2');
    });
    // 由于p1执行较快,Promise的then()将获得结果'P1'。p2仍在继续执行,但执行结果将被丢弃。
    Promise.race([p1, p2]).then(function (result) {
        console.log(result); // 'P1'
    });
    

    相关文章

      网友评论

          本文标题:JavaScript Promise的用法

          本文链接:https://www.haomeiwen.com/subject/qpdylftx.html