Javascript 直接使用$http承诺

Javascript 直接使用$http承诺,javascript,angularjs,Javascript,Angularjs,我的服务器总是以{meta:,reply:}的形式返回数据。所以,在我的角度服务中,我试图返回回复部分 下面的代码不起作用 function get(url) { return $http.get(url) .success(function(d){ //d {meta:<> , reply:<>} return d.reply }) } get("/a/b/c").then(function(d){

我的服务器总是以
{meta:,reply:}
的形式返回数据。所以,在我的角度服务中,我试图返回回复部分

下面的代码不起作用

function get(url) {
     return $http.get(url)
        .success(function(d){ //d {meta:<> , reply:<>}
            return d.reply
        })
}

get("/a/b/c").then(function(d){
    console.log(d) // prints server response ({meta:<> , reply:<>}); not reply
})
函数get(url){
返回$http.get(url)
.success(函数(d){//d{meta:,回复:}
回复
})
}
获取(“/a/b/c”)。然后(函数(d){
log(d)//打印服务器响应({meta:,reply:});而不是reply
})
但是,如果我使用$q并解决承诺问题,它就会起作用。但是,我想我可以直接使用$http返回的承诺。这两者在逻辑上有区别吗?怎么了

function get(url) {
    var deferred = $q.defer();
     $http.get(url)
        .success(function(d){ //d {meta:<> , reply:<>}
            deferred.resolve(d.reply)
        })
    return deferred.promise;
}

get("/a/b/c").then(function(d){
    console.log(d) // prints reply part of server response
})
函数get(url){
var deferred=$q.deferred();
$http.get(url)
.success(函数(d){//d{meta:,回复:}
延期。决议(d.答复)
})
回报。承诺;
}
获取(“/a/b/c”)。然后(函数(d){
log(d)//打印服务器响应的应答部分
})

这是因为当解析
$http.get
时,承诺将完成,并在数据中传递给函数。在这种情况下,“d”

从本页:

“返回带有标准
然后
方法和两个http特定方法的承诺对象:
success
error
then
方法接受两个参数,一个是success,一个是error回调,它将通过response对象调用。
success
error
方法采用一个参数-当请求成功或失败时分别调用该函数。传递给这些函数的参数是传递给
然后
方法的响应对象的非结构化表示。”


因此,
then
方法得到的是响应,而不是您成功返回的响应。

既然$http已经返回,那么您可以这样做:

在您的第一个“坏”示例中,.success()实际上没有做任何事情。成功回调的返回值根本没有被使用,您仍然只是返回$http承诺,该承诺将使用整个响应数据解析(而不仅仅是d.reply).如果您只想返回d.reply,那么第二个示例就是正确的方法

success函数本身返回的promise对象与方法链接的$http.get相同。因此:

function get(url) {
     return $http.get(url)
        .success(function(d){ //d {meta:<> , reply:<>}
            return d.reply
        })
}

get("/a/b/c").then(function(d){
    console.log(d) // prints server response ({meta:<> , reply:<>}); not reply
})
函数get(url){
返回$http.get(url)
.success(函数(d){//d{meta:,回复:}
回复
})
}
获取(“/a/b/c”)。然后(函数(d){
log(d)//打印服务器响应({meta:,reply:});而不是reply
})
与此完全相同:

function get(url) {
     return $http.get(url);
}

get("/a/b/c").then(function(d){
    console.log(d) // prints server response ({meta:<> , reply:<>}); not reply
})
函数get(url){
返回$http.get(url);
}
获取(“/a/b/c”)。然后(函数(d){
log(d)//打印服务器响应({meta:,reply:});而不是reply
})
执行此操作时,您将返回对.success()的调用的返回值,这是原始的$http承诺。您不会返回回调的返回值

return $http.get(url)
.success(function(d){ //d {meta:<> , reply:<>}
    return d.reply
})
返回$http.get(url)
.success(函数(d){//d{meta:,回复:}
回复
})

我不确定这是否正确。$http.get返回一个承诺,通常可以与.then链接(我想成功只是一个包装器)。因此,我链接返回d.reply,这应该在下次调用之前解决。但是,我可能错了,因为我无法解释错误的行为。是的,它是正确的。您的get(url)函数正在返回.success()之前的原始承诺方式回调曾经被执行过。如果我调试/放置控制台日志,我可以看到调用的成功处理程序。因此,它被调用了。可能在我调用时它没有被解析。它被调用了,但返回值对您没有帮助。请仔细阅读这里发生的代码。记住,成功回调是异步调用的(当您的ajax调用完成时)。但是您对原始承诺的返回是同步进行的(在您的ajax调用完成之前)。您当时怎么可能有ajax响应?+1,它说明了这个问题。但是,为什么我不能使用success handler?您可能希望检查Pawel Kozlowski的回答