AngularJS和Q.fcall

时间:2014-02-22 07:50:36

标签: javascript angularjs promise q

Angulars $q是受Kris Kowal Q启发的承诺/延期实施。

在Q中,您使用

创建承诺
var myPromise = Q.fcall(myFunction);

这里myFunction将异步调用,一个promise放在myPromise变量中,代码继续执行。

only example Angular用于创建承诺是使用javascript timeout函数,与上面的Q示例相比,这对我来说似乎是一个冗长的hack。所以在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中异步调用函数并返回promise的最简单方法是什么?

6 个答案:

答案 0 :(得分: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库函数的数量已经在调用时返回一个promise。与$timeout$http$resource一样。

答案 1 :(得分:2)

我不知道这是否非常聪明,但它对我有用:

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

fcall(123).then(function(values) {
    console.log(values); // 123
});

答案 2 :(得分:1)

好的,更清洁的替代方案是注入Angular的$timeout,让我们再说一下,函数myFunction是我想要异步完成的工作,我只会这样做:

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

doWorkAsync将返回一个承诺,该承诺将在myFunction完成其工作时解决。

对于单元测试,我可以调用$timeout.flush()立即触发超时功能。

答案 3 :(得分: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
        }
    }

答案 4 :(得分:0)

您可以使用$ q作为类似于ES6工作方式的构造函数。

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

angular docs

答案 5 :(得分:0)

您可以使用Q.fcall(fn)来模仿$q.when().then(fn)。它稍微冗长一些,但作用相同。

var myPromise = $q.when().then(myFunction);

其中myFunction可以是异步的也可以是同步的,并且将使用未定义的参数进行调用。

工作示例:

// Node.js
var Q = require('q');
var updatePromise = Q.fcall(function() {
    if (isUpdate) {
        return doAsyncUpdate();
    } else {
        return doSyncDelete();
    }
}).catch(function(err) {
    handleError(err);
});

// AngularJS
['$q', function($q) {
    var updatePromise = $q.when().then(function() {
        if (isUpdate) {
            return doAsyncUpdate();
        } else {
            return doSyncDelete();
        }
    }).catch(function(err) {
        handleError(err);
    });
}]

文档:https://docs.angularjs.org/api/ng/service/$q#when

请注意,$q.whenQ.when的工作原理相同。