2014-02-22 50 views
2

Angulars $q是克里斯·科瓦爾的Q.啓發承諾/延期執行AngularJS和Q.fcall

在Q,你創建

var myPromise = Q.fcall(myFunction); 

這裏myFunction承諾將異步調用,一個承諾放置在myPromise變量中,並繼續執行代碼。

only example角度給出了創造一個承諾是使用javascript timeout函數,這對我來說似乎是一個冗長的破解與上面的Q例子相比。所以在Angular中,我會寫

function asyncWorker(name) { 
    var deferred = $q.defer(); 

    setTimeout(function() { 
    scope.$apply(function() { 
     deferred.resolve(myFunction); 
    }); 
    }, 1000); 

    return deferred.promise; 
} 

上面的內容與頂部的單行相同。

我希望$q.fcall會的工作,但我得到:

TypeError: 'undefined' is not a function (evaluating '$q.fcall(function() { return 'a'; })') 

那麼什麼是異步調用的函數,並返回在AngularJS承諾的最簡單的方法是什麼?

回答

1

好,更清潔的替代被注入角的$timeout,讓我們再說一遍這個函數myFunction是我想asynchroniously做的工作,我只是做:

function doWorkAsync() { 
    return $timeout(myFunction, 10); 
} 

doWorkAsync會返回一個承諾,這將是當myFunction完成它的工作時解決。

對於單元測試,我可以撥打$timeout.flush()立即啓動超時功能。

+1

這是一個很好的答案,但值得說明的是,它並不像使用defer()那樣完全模擬'fcall',因爲'defer'可以像'fcall'一樣同步運行,但'$ timeout'是異步的。 – marksyzm

3

您正在尋找這樣的事情

function doWorkAsync() { 
    var defer = $q.defer(); 
    //do some work async and on a callback 
    asyncWork(function(data)) { 
     defer.resolve(data); 
    } 
    return defer.promise; 
} 

現在你調用這個函數

doWorkAsync().then(function(data)); 

angularJS庫函數的數量已經在調用返回的承諾。像$timeout$http$resource

+0

不,我要問的是如何創建'asyncWork'如果它是你必須做一些實實在在的工作,而不是你調用像'$ http'異步服務。 – vertti

+0

據我所知,javascript是單線程的(通過簡化)。你需要看看WebWorker https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers – Chandermani

+0

@vertti:你的意思是「真正的工作」是什麼?如果它沒有異步組件,爲什麼還需要promise? – Bergi

2

我不知道這是不是很聰明,但它爲我工作:

function fcall(someValues) { 
    var deferrd = $q.defer(); 
    deferrd.resolve(someValues); 
    return deferrd.promise; 
} 

fcall(123).then(function(values) { 
    console.log(values); // 123 
}); 
0
function createPromise(func) { 
     return function (params) { 
      var deferred = $q.defer(); 

      $timeout(function() { 
       try { 
        var rtn = func(params); 
        deferred.resolve(rtn); 
       } 
       catch (ex) { 
        deferred.reject(); 
       } 

      }) 
      return deferred.promise 
     } 
    } 
0

你可以使用$ Q類似於ES6是如何工作的一個構造函數。

function asyncGreet(name) { 
    return $q(function(resolve, reject) { 
    resolve('Hello, ' + name + '!'); 
    }); 
} 

angular docs