AngularJS中$q的promise运用及链式挪用传值题目

promise是什么

这里不诠释promise是什么,由于我相信你来看文章的时刻已晓得你什么是promise了。
此处有promise范例。

Promise/A+范例 中文
Promise/A+
ES2016:MDN Promise

$q

  • $q是AngularJS供应的一个效劳。

  • $q是跟AngularJS的$rootScope模板集成的,所以在AngularJS中实行和谢绝都很快。(编辑器疯了,dollar标记就是打不出来,就叫 ‘dollar’q)

  • $q是跟AngularJS模板引擎集成的,这意味着在视图中找到任何Promise都邑在视图中被实行或许谢绝。

如安在AngularJS中运用

直接上栗子,程序员都不喜好听你空话~〒▽〒

        var app = angular.module('app', [])
            .controller('testController', function ($scope, $q) {
                //定义一个defer
                var defer = $q.defer();
                var promise = defer.promise;
                promise.then(function (data) {
                    //胜利后的逻辑处置惩罚
                }, function (error) {
                    //失利后的逻辑处置惩罚
                });
                //模仿经由过程--现实应该是一个异步的callback中挪用
                defer.resolve('[data]');
                //模仿谢绝--现实应该是一个异步的callback中挪用
                defer.reject('[data]');
            });

链式挪用

then会返回一个新的promise对象,所以直接jQuery作风的链式挪用。
照样直接上栗子:

        var app = angular.module('app', [])
            .controller('testController', function ($scope, $q) {
                //定义一个defer
                var defer = $q.defer();
                var promise = defer.promise;
                promise.then(function () {
                    console.log('then-resolved-1');
                }, function () {
                    console.log('then-rejected-1');
                })
                .then(function () {
                    console.log('then-resolved-2');
                }, function () {
                    console.log('then-rejected-2');
                });
                //模仿经由过程--现实应该是一个异步的callback中挪用
                defer.resolve('[data]');
                //模仿谢绝--现实应该是一个异步的callback中挪用
                defer.reject('[data]');
            });

来看下是怎样完成链式挪用的,下面是AngularJS源码完成:

//angular.js
  Promise.prototype = {
    then: function(onFulfilled, onRejected, progressBack) {
      var result = new Deferred();//此处能够看出,每一个then都邑返回一个新的Deferred对象。

      this.$$state.pending = this.$$state.pending || [];
      this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);
      if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);

      return result.promise;
    },
    //其他省略
    ...
    }
//Deferred定义
  function Deferred() {
    this.promise = new Promise();//能够看到defer的promise对象是一个new Promise()
    //Necessary to support unbound execution :/
    this.resolve = simpleBind(this, this.resolve);
    this.reject = simpleBind(this, this.reject);
    this.notify = simpleBind(this, this.notify);
  }

链式挪用参数通报

看过上面链式挪用的栗子和AngularJS的源码后,人人就可以晓得每一个then的上下文现实上是不一样的,由于每次都是新new 出来的Promise对象。
先给栗子:

    var app = angular.module('app', [])
        .controller('testController', function ($scope, $q) {
            //定义一个defer
            var defer = $q.defer();
            var promise = defer.promise;
            promise.then(function (data) {
                //...
                return data;// data = 1
            }, function (error) {
                //...
            })
            .then(function (data) {
                //...
                return data;//data = 1
            }, function (error) {
                //...
            });
            //模仿经由过程--现实应该是一个异步的callback中挪用
            defer.resolve('1');
        });

接下来看一段源码剖析,看看AngularJS是怎样挪用Promise的。

//angular.js
 Deferred.prototype = {
    resolve: function(val) {
      if (this.promise.$$state.status) return;
      if (val === this.promise) {
        this.$$reject($qMinErr(
          'qcycle',
          "Expected promise to be resolved with value other than itself '{0}'",
          val));
      }
      else {
        this.$$resolve(val);//现实挪用这个要领
      }

    },

    $$resolve: function(val) {
      var then, fns;

      fns = callOnce(this, this.$$resolve, this.$$reject);
      try {
        if ((isObject(val) || isFunction(val))) then = val && val.then;
        if (isFunction(then)) {
          this.promise.$$state.status = -1;
          then.call(val, fns[0], fns[1], this.notify);
        } else {
          this.promise.$$state.value = val;
          this.promise.$$state.status = 1;
          scheduleProcessQueue(this.promise.$$state);//终究在此处加入到行列中
        }
      } catch (e) {
        fns[1](e);
        exceptionHandler(e);
      }
    },...
    
    //scheduleProcessQueue定义
   function scheduleProcessQueue(state) {
    if (state.processScheduled || !state.pending) return;
    state.processScheduled = true;
    nextTick(function() { processQueue(state); });//此处挪用进入processQueue
  }

 function processQueue(state) {
    var fn, promise, pending;

    pending = state.pending;
    state.processScheduled = false;
    state.pending = undefined;
    for (var i = 0, ii = pending.length; i < ii; ++i) {
      promise = pending[i][0];
      fn = pending[i][state.status];
      try {
        if (isFunction(fn)) {
          promise.resolve(fn(state.value));//此处是链式挪用传参症结,fn(state.value)现实是上一个then的resolve的返回值,所以能晓得,假如须要一切的then都能取到异步使命的返回值,就得在then的resolve函数中,将值返回。
        } else if (state.status === 1) {
          promise.resolve(state.value);
        } else {
          promise.reject(state.value);
        }
      } catch (e) {
        promise.reject(e);
        exceptionHandler(e);
      }
    }
  }
    原文作者:咸鱼爱吃梨
    原文地址: https://segmentfault.com/a/1190000005272225
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞