当我们在$ q中调用普通函数时,这项工作是否异步?

时间:2016-09-22 07:12:36

标签: angularjs

        *

// for the purpose of this example let's assume that variables `$q` and `okToGreet`
            // are available in the current lexical scope (they could have been injected or passed in).
          // perform some asynchronous operation, resolve or reject the promise when appropriate.


        function asyncGreet(name) {

          return $q(function(resolve, reject) { //function to call in $q
            setTimeout(function() {
              if (okToGreet(name)) {
                myFun()////call function in here which is not async
                resolve('Hello, ' + name + '!');//call function in here
              } else {
                reject('Greeting ' + name + ' is not allowed.');
              }

            }, 1000);
          });
        }

  // for the purpose of this example let's assume that variables `$q` and `okToGreet`
        // are available in the current lexical scope (they could have been injected or passed in).
      // perform some asynchronous operation, resolve or reject the promise when appropriate.
//function to call in $q

*

1 个答案:

答案 0 :(得分:1)

$ q 用于管理javascript中的异步环境,这在事件编程中是典型的。 $ q 中的回调也是异步的,这意味着它将在当前调用堆栈之后调用(在您的示例中,它将是setTimeout回调函数作为当前调用堆栈)。我准备了一些例子:

var app=angular.module("app",[]);

app.controller("cont",function($q){

  function asyncGreet() {

  var deferred = $q.defer();  
     
  setTimeout(function(){
      
       console.log("-- Standard log 1");
       
       //example asnychronous call using setTimeout
       setTimeout(function(){ console.log("--- Call in timeout 2");});

       //our function is called as third
       deferred.resolve();

       console.log("-- Standard log 4");
       console.log("-- Standard log 5");
       
  },1000);
    
  return deferred.promise;  
    
  };  
            
            
  
  console.log("- asyncGreat call 0");

  asyncGreet().then(function(){
  
    console.log("--- Resolve log 3");
    
  });
  
  console.log("- after asyncGreat call 6");
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="cont">
</div>  

在中间调用Resolve,但在控制台中我们看到最后调用。 Reason是 $ q 的异步行为,在当前调用堆栈之后调用回调,因此在setTimeout中的所有代码之后调用。

同样的情况是没有时间调用setTimeout,它将在当前调用堆栈之后异步运行。

我故意在控制台日志中设置数字,数字显示代码中的调用位置,但$ q和超时的异步表示代码中的位置和真实调用它们不匹配。

对于这个问题,no - only resolve和reject将异步运行到当前调用堆栈,标准函数调用将以标准方式运行,但在你的例子中我们在1sec后有setTimeout,所以更复杂的调用堆栈如下:

- asyncGreat() call
-- async call of setTimeout callback after 1s
--- async call code in second setTimeout
--- async call code in resolve