Promise in JavaScript

WHY

Promise是一个古老的概念(1976),又叫Deferred(延期的),Futurejava.util.concurrent.Future
JavaScript是单线程,为了防止线程阻塞,在JS中有一种写法叫做回调

1
2
3
$.get('/users/123', function(user) {
//这里可以对User进行一些操作
})

这样就解决了JS单线程的问题了,但是又引出了一个新的问题 回调地狱

1
2
3
4
5
6
7
$.get('/users/123', function(class) {
$.get('/class/4', function(school) {
$.get('/schooles/123/chairman', function(class) {
console.log('get data');
})
})
})

回调地狱存在的明显的问题 难读而且也难测。然后为了解决这些问题,降低异步编程的复杂性,开发人员一直寻找简便的方法来处理异步操作,就出现了一个概念Promise和Promise的一系列的实现。Promise代表了一种可能会长时间运行而且不一定必须完整的操作的结果.

WHAT

所谓Promise,字面上可以理解为”承诺”,就是说A调用B,B返回一个”承诺”给A,然后A就可以在写计划的时候这么写:当B返回结果给我的时候,A执行方案S1,反之如果B因为什么原因没有给到A想要的结果,那么A执行应急方案S2,这样一来,所有的潜在风险都在A的可控范围之内了。

Promise有三种状态

  • pending: 初始状态, new
  • fulfilled: 表示操作成功//success callback
  • rejected: 表示操作失败//failure callback

HOW

  • promise.then(success,failure),promise.catch(failure)

    promise.catch(failure)相当于promise.then(null, failure)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
      vm.promise1 = function() {
    $http.get('/users')
    .then(function(data) {
    console.log('success1');
    return $http.get('/users/success');
    }, function() {
    console.log('error1');
    })
    .then(function() {
    console.log('success2');
    return $http.get('/users/error');
    }, function() {
    console.log('error2');
    })
    .catch(function() {
    console.log('error3');
    })
    .finally(function() {
    console.log('finally');
    });
    }
    //success1
    //success2
    //GET http://localhost:3000/users/error 500 (Internal Server Error)
    //error3
    //finally
  • 如果 Promise 被 reject,后面的 then 又没有指定失败回调,会找后面的失败回调。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $http.get('/users/error')
    .then(function(data) {
    console.log('success1');
    })
    .then(function() {
    console.log('success2');
    }, function() {
    console.log('error1');
    })
    .catch(function() {
    console.log('error2');
    })
    .finally(function() {
    console.log('finally');
    });

    //GET http://localhost:3000/users/error
    //view1.js:44 error2
    //view1.js:50 finally
  • 如果Promise失败,那么失败回调后会调用下一个then的成功回调

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $http.get('/users/error')
    .catch(function() {
    console.log('error1');
    })
    .then(function(data) {
    console.log('success1');
    })
    .finally(function() {
    console.log('finally');
    });
    //GET http://localhost:3000/users/error 500 (Internal Server Error)
    //error1
    // success1
    // finally
  • 如果Promise失败且返回了一个Promise,在后面的then的参数里会被拆开。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    $http.get('/users/error')
    .catch(function() {
    $http.get('/users/success')
    })
    .then(function(data) {
    console.log('success1');
    }, function() {
    console.log('error1')
    })
    .finally(function() {
    console.log('finally');
    });

    //GET http://localhost:3000/users/error 500 (Internal Server Error)
    //success1
    //finally
  • angular的all, defer, reject方法

  • 不仅仅是Ajax

MORE

OTHERS

2015前端生态发展回顾

  • 年初React Native的发布,引领React正式走上历史舞台。
  • 3月angular2.0第一个预览版发布
  • 5月 http/2.0标准正式发布,同月 iojs 与 nodejs合并。
  • 6月 ES6 和 WebAssembly 落地
  • 7月 迄今为止React生态圈影响最大的Flux实现redux发布1.0版本
  • 8月 Facebook公开了在React上应用GraphQL的relay框架的技术预览版
  • 9月 React Native for Andriod 发布
  • 11月伊始,es标准委员会宣布将历时3年研究的Object.observe从草案中移除,尽管它原本已经是stage2,几乎已经是ES7的事实标准。双十一刚一结束,阿里手淘团队发布了名为 无线电商动态化解决方案 的 Weex,也有人给了它一个更具象的名字,vue native。
  • 12月,赶在2015的尾巴,aurelia和angular2先后发布beta版。