Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/82.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 将.then()lambda表达式的结果作为函数结果返回_Javascript_Jquery_Ajax_Promise_Jqxhr - Fatal编程技术网

Javascript 将.then()lambda表达式的结果作为函数结果返回

Javascript 将.then()lambda表达式的结果作为函数结果返回,javascript,jquery,ajax,promise,jqxhr,Javascript,Jquery,Ajax,Promise,Jqxhr,我对js比较陌生,所以如果我的措辞不太正确,请原谅我。我还创建了一个示例来演示这个问题 概述 在我正在开发的应用程序中,我有一个带有jquery ajax调用的函数,如下所示: function scenario1(ajaxCfg) { return $.ajax(ajaxCfg) } function callDependency() { //example dependency return $.ajax(depUri) } function scenario2(ajax

我对js比较陌生,所以如果我的措辞不太正确,请原谅我。我还创建了一个示例来演示这个问题

概述

在我正在开发的应用程序中,我有一个带有jquery ajax调用的函数,如下所示:

function scenario1(ajaxCfg) {
    return $.ajax(ajaxCfg)
}
function callDependency() { //example dependency
    return $.ajax(depUri)
}

function scenario2(ajaxCfg) {
    return callDependency().then(() => $.ajax(ajaxCfg))
}
我想更改此函数,但不以任何方式更改输入或输出(因为此函数在我的应用程序中被调用数百次)

更改是进行不同的ajax调用,然后进行指定的调用。我现在写的是这样的:

function scenario1(ajaxCfg) {
    return $.ajax(ajaxCfg)
}
function callDependency() { //example dependency
    return $.ajax(depUri)
}

function scenario2(ajaxCfg) {
    return callDependency().then(() => $.ajax(ajaxCfg))
}
期望的结果

我希望这两个返回的对象相同:

let result1 = scenario1(exampleCall)
let result2 = scenario2(exampleCall)
更具体地说,我希望
result2
返回与
result1
相同类型的对象

实际结果

result1
显然是ajax调用的结果,它是一个实现promise接口的
jqXHR
,并解析为与标准promise的
result2
相同的值

由于
result2
不是
jqXHR
对象,
result2.error()
未定义,而
result1.error()已定义

我确实尝试模拟这些方法(例如,简单地向返回结果添加一个
.error
函数),但不幸的是,即使这样做,
result1.done().error
是在
result2.done()时定义的。error
未定义的

将其包装(或展开)

简而言之,我想返回
scenario2
jqXHR
函数的
result.then()
lambda函数作为
scenario2
函数的结果。在伪代码中,我希望:

function scenario2(ajaxCfg) {
    return callDependency().then(() => $.ajax(ajaxCfg)).unwrapThen()
} //return jqXHR


我觉得如果使用async/await语法,您的生活会轻松得多。请记住,异步函数会返回一个承诺。所以你可以写:

async function scenario2(ajaxCfg) {
    let jqXhrResult;
    try {
        await callDependency();
        jqXhrResult = {
            jqXhr: $.ajax(ajaxCfg)
        };
    } catch() {
        // Error handling goes here
    }

    return jqXhrResult;
}

像这样的怎么样?方法稍有不同,但最终您可以将
.done()
等链接到
scenario2()
函数:

const exampleCall={url:'https://code.jquery.com/jquery-1.12.4.min.js'};
const depUri={url:'https://code.jquery.com/jquery-1.12.4.min.js'};
函数callDependency(){//示例依赖项
return$.ajax(depUri).done(()=>console.log('returned callDependancy'))
}
让obj={//创建一个使用scenario2作为方法的对象,这样我就可以用defer.promise()绑定它
场景2:功能(ajaxCfg){
return$.ajax(ajaxCfg).done(()=>console.log('returned senario2'))//故意不调用exampleCall()函数
}
}
延迟=$.Deferred();//使用一些JQuery魔术来返回jqXHR
延迟承诺(obj);//将目标设定为承诺
defer.resolve(callDependency());//默认情况下在promise resolve上调用callDependency()
目标完成(()=>{
obj.scenario2()//解析以便调用callDependency()函数
}).scenario2(exampleCall).done(()=>{//在这里,您可以调用scenario2,并在调用所有内容后最终链接您想要的任何内容
console.log('在这里我可以用.done\(\)或.fail\(\)等链接我想要的任何东西。')
})

我实际上想到了一种更简单的方法

您可以通过向函数构造函数的原型对象添加方法来实现。这样,任何创建的函数都可以继承该方法,并且仍然可以使用
.done()
语法。它被称为:

const exampleCall={url:'https://code.jquery.com/jquery-1.12.4.min.js'};
const depUri={url:'https://code.jquery.com/jquery-1.12.4.min.js'};
函数callDependency(){
return$.ajax(depUri).done(()=>console.log('returned callDependancy'))
}
Function.prototype.scenario2=函数(ajaxCfg,…args){
返回此(…args)。然后(()=>$.ajax(ajaxCfg))
}
callDependency.scenario2(exampleCall).done(数据=>{
console.log(数据)
})

^^^^^ senario1在ajax调用之前没有返回,更迂腐一些:
$.ajax()
返回一个“jqXHR对象”,它不是一个
承诺
,而是一个实现
承诺
接口的对象。@Andreas oops!修正了。JSFIDLE是正确的,我只是抄错了。但还有一点:就是这样,我想要jgXHR对象。如何将其作为函数的返回值?一个
jqXHR
对象没有
.resolve()
.reject()
方法,因此它不是一个延迟对象。这实际上是一个(jQuery)承诺。您能具体说明您的主要目标是什么吗?您希望在这里实现什么?不幸的是,异步函数的结果不是jqXHR对象,因此它不支持相同的方法(例如
.done().error()
)。我已经更新了我的答案,以适应错误处理。在等待场景2函数之后,您可以将错误回调中的逻辑移到catch块中,并将完成回调的逻辑移到catch块中。关于jquery jqXHR/promise对象是如何解析的,这里有一个非常好的解释:我已经将您的建议添加到JSFIDLE中;我希望这能说明为什么这不是一个解决办法。如果我遗漏了什么,请告诉我。我再次更新了答案,并在此处进行了测试:。作为一个简短的提示,我真的不鼓励这样做,即使这样做是有效的。最好的方法是重构前端,使其符合asyc/WAIT语法,但我知道您可能会被迫不这样做,因为您提到此功能在您的应用程序中随处可见;您已将调用程序更改为在异步函数中运行,
async function runLogic()
。正如您所想象的,我不能修改应用程序中的每个调用程序,使其在异步函数中运行。但是,是的,我同意这不是一个构建新应用程序的好模式。我无法在