小昱个人博客
欢迎来到小昱的世界

勤学如春起之苗,不见其增,日有所长;辍学如磨刀之石,不见其损,日有所亏
es6之promise的使用
  • 首页 > 前端 > JavaScript
  • 作者:小昱
  • 2017年6月26日 18:05 星期一
  • 浏览:148
  • 字号:
  • 评论:0
  • 什么是promise

    一个 Promise 对象可以理解为一次将要执行的操作(常常被用于异步操作),使用了 Promise 对象之后可以用一种链式调用的方式来组织代码,让代码更加直观。而且由于 Promise.all 这样的方法存在,可以让同时执行多个操作变得简单。


    入门案例

    function helloWorld (ready) {
      return new Promise(function (resolve, reject) {
        if (ready) {
          resolve("Hello World!");
        } else {
          reject("Good bye!");
        }
      });
    }
    
    helloWorld(true).then(function (message) {
      alert(message);
    }, function (error) {
      alert(error);
    });

    resolve 方法可以使 Promise 对象的状态改变成成功,同时传递一个参数用于后续成功后的操作,在这个例子当中就是 Hello World! 字符串。

    reject 方法则是将 Promise 对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作。


    Promise 的三种状态

    • Fulfilled 可以理解为成功的状态

    • Rejected 可以理解为失败的状态

    • Pending 既不是 Fulfilld 也不是 Rejected 的状态,可以理解为 Promise 对象实例创建时候的初始状态


    then 和 catch

    then

    helloWorld 的例子当中利用了 then(onFulfilld, onRejected) 方法来执行一个任务打印 "Hello World!",在多个任务的情况下 then方法同样可以用一个清晰的方式完成。

    function printHello (ready) {
        return new Promise(function (resolve, reject) {
            if (ready) {
                resolve("Hello");
            } else {
                reject("Good bye!");
            }
        });
    }
    
    function printWorld () {
        alert("World");
    }
    
    function printExclamation () {
        alert("!");
    }
    
    printHello(true)
    .then(function(message){
      alert(message);
    })
    .then(printWorld)
    .then(printExclamation);

    上述例子通过链式调用的方式,按顺序打印出了相应的内容。then 可以使用链式调用的写法原因在于,每一次执行该方法时总是会返回一个 Promise 对象。另外,在 then onFulfilled 的函数当中的返回值,可以作为后续操作的参数,因此上面的例子也可以写成:

    printHello(true).then(function (message) {
        return message;
    }).then(function (message) {
        return message  + ' World';
    }).then(function (message) {
        return message + '!';
    }).then(function (message) {
        alert(message);
    });

    catch

    catch 方法是 then(onFulfilled, onRejected) 方法当中 onRejected 函数的一个简单的写法,也就是说可以写成 then(fn).catch(fn),相当于 then(fn).then(null, fn)。使用 catch 的写法比一般的写法更加清晰明确。

    // bad
    promise
      .then(function(data) {
        // success
      }, function(err) {
        // error
      });
    
    // good
    promise
      .then(function(data) { //cb
        // success
      })
      .catch(function(err) {
        // error
      });

    上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。


    Promise.all 和 Promise.race

    Promise.all 可以接收一个元素为 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为 resolve 时,该方法才会返回。

    var p1 = new Promise(function (resolve) {
        setTimeout(function () {
            resolve("Hello");
        }, 3000);
    });
    
    var p2 = new Promise(function (resolve) {
        setTimeout(function () {
            resolve("World");
        }, 1000);
    });
    
    Promise.all([p1, p2]).then(function (result) {
        console.log(result); // ["Hello", "World"]
    });

    上面的例子模拟了传输两个数据需要不同的时长,虽然 p2 的速度比 p1 要快,但是 Promise.all 方法会按照数组里面的顺序将结果返回。

    日常开发中经常会遇到这样的需求,在不同的接口请求数据然后拼合成自己所需的数据,通常这些接口之间没有关联(例如不需要前一个接口的数据作为后一个接口的参数),这个时候 Promise.all 方法就可以派上用场了。

    还有一个和 Promise.all 相类似的方法 Promise.race,它同样接收一个数组,不同的是只要该数组中的 Promise 对象的状态发生变化(无论是 resolve 还是 reject)该方法都会返回。



    参考资料

    谈谈 ES6 的 Promise 对象

    阮一峰 - es6入门 Promise 对象

    JavaScript Promise迷你书(中文版)



      您阅读这篇文章共花了:  
    二维码加载中...
    本文作者:小昱      文章标题: es6之promise的使用
    本文地址:http://www.xiaoyulive.top/?post=102
    版权声明:若无注明,本文皆为“小昱个人博客”原创,转载请保留文章出处。
    返回顶部| 首页| 碰碰手气| 捐赠支持| 手机版本|后花园

    Copyright © 2016-2017 小昱个人博客 滇ICP备16006294号