Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 拒绝AngularJS中带有多个参数(如$http)的承诺_Javascript_Angularjs - Fatal编程技术网

Javascript 拒绝AngularJS中带有多个参数(如$http)的承诺

Javascript 拒绝AngularJS中带有多个参数(如$http)的承诺,javascript,angularjs,Javascript,Angularjs,$http承诺的回调有多个参数:body、status、headers、config 我想亲手创造类似的承诺,但不知道如何做到这一点。我想做的或多或少是: myservice.action().then(function(status, message, config) { // ... }); 我知道我可以将带有键的对象传递给回调,但希望有类似于$http中的约定。我看了角度源,但要么不完全理解,要么就是做不好 您知道如何创建能够向callback/errbacks传递多个参数的承诺

$http
承诺的回调有多个参数:body、status、headers、config

我想亲手创造类似的承诺,但不知道如何做到这一点。我想做的或多或少是:

myservice.action().then(function(status, message, config) {
    // ...
});
我知道我可以将带有键的对象传递给回调,但希望有类似于
$http
中的约定。我看了角度源,但要么不完全理解,要么就是做不好


您知道如何创建能够向callback/errbacks传递多个参数的承诺吗?

如评论中所建议的,请查看AngularJS的
$q
。这些医生因。。。有时候很难理解

但不管怎样,让我们试试一个简短的例子。我在CoffeeScript中这样做,因为我更喜欢它,但是如果您愿意,您应该能够在编译示例

让我们实现一个服务:

app = angular.module 'my.custom.services', ['your.other.modules']

app.factory 'Service', ['$http' , '$q', (http, q) ->

  # this is your deferred result
  deferred = q.defer()

  get: ->
    deferred.promise
]
这个很简单。这只是一个服务,它将使用
$q
$http
,因为a)我们想要一些我们正在谈论的基于承诺的东西,b)“$http”本身就是一个很好的例子,它可以调用异步,但其结果现在不可用

这里有趣的部分是返回的对象的
get
部分。请注意,该服务是作为
工厂
实现的,而不是作为
服务
实现的。有关差异,请参阅。我通常认为它是一个服务的“奇特”版本,在公开服务的API之前,我只需要为自己的逻辑留出一些额外的空间(它确实意味着一些不同的东西,但这是另一个故事)

无论如何,
get
在调用时将返回延迟对象的
promise
promise
是一个对象,它公开了一个
then
方法。使用此服务时,您可能会像这样注入它:

app = angular.module 'my.custom.application', ['my.custom.services']

app.controller 'AppController', ['Service', (service)->

  service.get() # then what?

]
正如我提到的,
get
只会返回一个承诺。承诺,就像在现实生活中一样,必须在某个地方得到解决。所以让我们在服务中这样做——我们的承诺会得到解决,只要我们完成了承诺的任务。这可能类似于通过AJAX调用URL或进行大型计算(谁知道第117个斐波那契数是什么?)

在我们的示例中,我们使用http调用,无论它是否返回,甚至何时返回,我们现在都不这样做:

app.factory 'Service', ['$http' , '$q', (http, q) ->

  # this is your deferred result
  deferred = q.defer()

  # this is where http is used, this is started immediately, but takes a while
  http.get('some-resource.json').then (response) ->
    # now 'response' is the whole successful response, it has a data object with the payload
    if !someCondition
      deferred.resolve response.data #we have what we wanted
    else
      deferred.reject {error: "Failed", additional: "foo", number: 2} #we ran into some error

  get: ->
    deferred.promise
]
基于
someCondition
,如果我们愿意,我们可以故意让请求失败。如果您想自己尝试,也可以像文档中一样使用
超时

现在发生了什么?好吧,我们周围还有控制器:

app.controller 'AppController', ['Service', (service)->

  service.get().then(successCallback, errCallback)

]
正如我所解释的,
promise
公开了一个签名为
then(success,error)
then
方法,其中
success
error
是将我们解析的任何内容作为参数的函数,例如:

app.controller 'AppController', ['Service', (service)->
  successCallback = (data) ->
    # we can work with the data from the earlier resolve here
    scope.data = data

  errCallback = (err) ->
    # the error object, we got from the rejection
    console.log err.error # => "Failed"

  service.get().then(successCallback, errCallback)

]
如果希望将多个值传递给回调,我建议您在解析/拒绝承诺时传递一个对象。您还可以为承诺执行命名回调,就像angular在其
$http
实现中所做的那样:

app.factory 'Service', ['$http' , '$q', (http, q) ->

  # this is your deferred result
  deferred = q.defer()

  # [...]

  get: ->
    promise = deferred.promise

    promise.success = (fn) ->
      promise.then (data) ->
       fn(data.payload, data.status, {additional: 42})
      return promise

    promise.error = (fn) ->
      promise.then null, (err) ->
        fn(err)
      return promise

    return promise 
]
实际上,您扩展了方法
success
返回的承诺,该方法将单个方法作为回调,等待承诺被解析,然后使用回调。如果愿意,您可以对任何其他方法执行相同的操作(有关提示,请参阅示例)

在控制器中,您可以这样使用它:

service.get().success (arg1, arg2, arg3) ->
  # => arg1 is data.payload, arg2 is data.status, arg3 is the additional object
service.get().error (err) ->
  # => err
这是基础,如果你愿意,你可以尝试,我建议你尝试以下方法:

  • 具有多个延迟承诺的服务中的多个承诺
  • 尝试另一种推迟结果的方法,比如长时间的计算
作为奖励:

  • 尝试将成功/错误回调隔离到服务的命名方法中

这个例子在Angular中使用了
$q
实现,您当然可以使用另一个实现来实现承诺,比如,它是
$q

查看的Angulars实现的基础。您为什么不像{status:'',message:'',config:''}@Ben那样传递数据呢?我正在查看它,但根本不知道它是如何工作的(我只是从所有承诺的东西开始)。举个例子就好了。@Ajay正如我提到的,我希望保持与
$http
承诺类似的惯例。据我所知,您只能传递一个参数来拒绝()根据specLove,你的promise.success和promise.error方法。谢谢你的提示,非常方便!希望你不介意我在这里引用了你的答案,因为这是谷歌首次对promise多个参数给出结果: