Javacript和AngularJS中的Promises页面调用

    作者:课课家教育更新于: 2016-02-18 16:05:33

    大神带你学编程,欢迎选课

      promise是javascript异步编程很好的解决方案。对于一个异步方法,执行一个回调函数。

    Javacript和AngularJS中的Promises页面调用_java程序执行_课课家

      比如页面调用google地图的api时就使用到了promise。

      function success(position){

      var cords = position.coords;

      console.log(coords.latitude + coords.longitude);

      }

      function error(err){

      console.warn(err.code+err.message)

      }

      navigator.geolocation.getCurrentPosition(success, error);

      ■ 如何处理多个异步方法

      如果有很多异步方法需要按序执行呢?async1(success, failure), async2(success, failure), ...asyncN(success, failure),该如何处理呢?

      最简单的,可能会这样写:

      async1(function(){

      async2(function(){

      asyncN(null, null);

      ...

      }, null)

      }, null)

      以上的代码是比较难维护的。

      我们可以让所有的异步方法执行完毕后出来一个通知。

      var counter = N;

      function success(){

      counter--;

      if(counter === 0){

      alert(‘done‘);

      async1(success);

      async2(success);

      asyncN(success);

      ■ 什么是Promise和Deferred

      deferred表示异步操作的结果,提供了一个显示操作结果和状态的接口,并提供了一个可以获取该操作结果相关的promise实例。deferred是可以改变操作状态的。

      promise提供了一个用来和相关deferred交互的接口。

      当创建一个deferred,相当于一个pending状态;

      当执行resolve方法,相当于一个resolved状态。

      当执行reject方法,相当于一个rejected状态。

      我们可以在创建deferred之后,定义回调函数,而回调函数在得到resolved和rejected的状态提示后开始执行。异步方法不需要知道回调函数如何操作,只需要在得到resolved或rejected状态后通知回调函数开始执行。

      ■ 基本用法

      → 创建deferred

      var myFirstDeferred = $q.defer();

      这里,对于myFirstDeferred这个deferred,状态是pending,接下来,当异步方法执行成功,状态变成resolved,当异步方法执行失败,状态变成rejected。

      → Resolve或Reject这个dererred

      假设有这样的一个异步方法:async(success, failure)

      async(function(value){

      myFirstDeferred.resolve(value);

      }, function(errorReason){

      myFirstDeferred.reject(errorReason);

      })

      在AngularJS中,$q的resolve和reject不依赖上下文,大致可以这样写:

      async(myFirstDeferred.resolve, myFirstDeferred.reject);

      → 使用deferred中的promise

      var myFirstPromise = myFirstDeferred.promise;

      myFirstPromise

      .then(function(data){

      }, function(error){

      })

      deferred可以有多个promise.

      var anotherDeferred = $q.defer();

      anotherDeferred.promise

      .then(function(data){

      },function(error){

      })

      //调用异步方法

      async(anotherDeferred.resolve, anotherDeferred.reject);

      anotherDeferred.promise

      .then(function(data){

      }, function(error){

      })

      以上,如果异步方法async成功执行,两个success方法都会被调用。

      → 通常把异步方法包裹到一个函数中

      function getData(){

      var deferred = $q.defer();

      async(deferred.resolve,deferred.reject);

      return deferred.promise;

      }

      //deferred的promise属性记录了达到resolved, reject状态所需要执行的success和error方法

      var dataPromise = getData();

      dataPromise

      .then(function(data){

      console.log(‘success‘);

      }, function(error){

      console.log(‘error‘);

      })

      如果只关注success回调函数该如何写呢?

      dataPromise

      .then(function(data){

      console.log(‘success‘);

      })

      如果只关注error回调函数该如何写呢?

      dataPromise

      .then(null, function(error){

      console.log(‘error‘);

      })

      或

      dataPromise.catch(function(error){

      console.log(‘error‘);

      })

      如果不管回调成功或失败都返回相同的结果呢?

      var finalCallback = function(){

      console.log(‘不管回调成功或失败都返回这个结果‘);

      }

      dataPromise.then(finalCallback, finalCallback);

      或

      dataPromise.finally(finalCallback);

      ■ 值链式

      假设有一个异步方法,使用deferred.resolve返回一个值。

      function async(value){

      var deferred = $q.defer();

      var result = value / 2;

      deferred.resolve(result);

      return deferred.promise;

      既然返回的是promise,我们就可以不断then, then下去的。

      var promise = async(8)

      .then(function(x){

      return x+1;

      })

      .then(function(x){

      return x*2;

      promise.then(function(x){

      console.log(x);

      以上,resolve出的值成为每一个链式的实参。

      ■ Promise链式

      function async1(value){

      var deferred = $q.defer();

      var result = value * 2;

      deferred.resolve(result);

      return deferred.promise;

      function async2(value){

      var deferred = $q.defer();

      var result = value + 1;

      deferred.resolve(result);

      return deferred.promise;

      var promise = async1(10)

      .then(function(x){

      return async2(x);

      promise.then(function(x){

      console.log(x);

      当然一种更易读的写法是:

      function logValue(value){

      console.log(value);

      async1(10)

      .then(async2)

      .then(logValue);

      async1方法的返回值成为then方法中的success方法中的实参。

      如果从捕获异常的角度,还可以这样写:

      async1()

      .then(async2)

      .then(async3)

      .catch(handleReject)

      .finally(freeResources);

      ■ $q.reject(reason)

      使用该方法能够让deferred呈现error状态,并给出一个出现error的理由。

      var promise = async().then(function(value){

      if(true){

      return value;

      } else {

      return $q.reject(‘value is not satisfied‘);

      ■ $q.when(value)

      返回一个promise并带上值。

      function getDataFrombackend(query){

      var data = searchInCache(query);

      if(data){

      return $q.when(data);

      } else {

      reutrn makeAasyncBackendCall(query);

      ■ $q.all(promisesArr)

      等待所有promise执行完成。

      var allPromise = $q.all([

      async1(),

      async2(),

      asyncN();

      allProise.then(function(values){

      var value1 = values[0],

      value2 = values[1],

      valueN = values[N];

      console.log(‘all done‘);

课课家教育

未登录