Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.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/2/jquery/85.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 $.when.apply.done根据数组的大小是一个还是多个返回不同的结果_Javascript_Jquery_Deferred - Fatal编程技术网

Javascript $.when.apply.done根据数组的大小是一个还是多个返回不同的结果

Javascript $.when.apply.done根据数组的大小是一个还是多个返回不同的结果,javascript,jquery,deferred,Javascript,Jquery,Deferred,我正在寻找一些关于执行多个ajax调用然后合并结果的最佳方法的建议。我的问题是,根据when函数的文档,当有多个参数与只有一个参数时,它将以不同的方式映射结果参数。 这导致代码如下所示。这张支票对我来说很难看,据我所知,每次使用$.when.apply时都需要进行检查。是否有一种方法可以将一组延迟传递给when函数,从而使输出具有一致的形状 //Returns an array of promises that are simple ajax get requests var getEvent

我正在寻找一些关于执行多个ajax调用然后合并结果的最佳方法的建议。我的问题是,根据when函数的文档,当有多个参数与只有一个参数时,它将以不同的方式映射结果参数。

这导致代码如下所示。这张支票对我来说很难看,据我所知,每次使用$.when.apply时都需要进行检查。是否有一种方法可以将一组延迟传递给when函数,从而使输出具有一致的形状

//Returns an array of promises that are simple ajax get requests
var getEventFramesPromises = self.webServiceAdapter.getEventFrames(distinctEventFramePaths);
$.when.apply($, getEventFramesPromises).then(function () {
            var eventFrames;
            //Now "arguments" will either be an array with three arguments it the length of the getEventFramesPromises ===1
            if (getEventFramesPromises.length === 1) {
                eventFrames = [arguments[0]];
            } else {
            //Or it will be an array of arrays where each item in the array represents a deferred result
                eventFrames = _.map(arguments, function (args) {
                    return args[0];
                });
            }});

不知道为什么这个问题会被否决。我认为这个问题是合理的,我指的是有问题的确切文件。因此,我最终采纳了Kevin的建议,编写了一个quick helper函数,该函数将提取jquery调用的结果,并考虑到数组中只有一个值时的行为

function extractValuesFromPromises() { 
        if (arguments.length === 3 && typeof arguments[2].then === 'function') {
            return [arguments[0]];
        } else {
            return _.map(arguments, function (args) {
                return args[0];
            });
        } 
    }
然后在你的代码中你可以这样做

var getEventFramesPromises = self.webServiceAdapter.getEventFrames(distinctEventFramePaths);
        $.when.apply($, getEventFramesPromises)
            .then(extractValuesFromPromises)
            .then(function (eventFrames) {
                //Do whatever with ajax results
});
jQuery
$。when()
可能是jQuery集中设计最差的API。它不仅根据您传递的数据返回不同的数据类型,而且它甚至不接受数组作为参数,这是最常用和灵活的使用方法。我建议的是一个简单的包装,它“修复”了设计的一致性:

// Takes an array of promises and always returns an array of results, even if only one result
$.all = function(promises) {
    if (!Array.isArray(promises)) {
        throw new Error("$.all() must be passed an array of promises");
    }
    return $.when.apply($, promises).then(function () {
        // if single argument was expanded into multiple arguments, then put it back into an array
        // for consistency
        var args = Array.prototype.slice.call(arguments, 0);
        if (promises.length === 1 && arguments.length > 1) {
            // put arguments into an array for consistency
            return [args];
        } else {
            return args;
        }
    });
};
这里有一个稍微不同的实现,它还采用了
$.ajax()
解析为的三元素数组,并使其成为单个数据值,因此解析的值只是单个元素结果的简单数组:

// jQuery replacement for $.when() that works more like Promise.all()
// Takes an array of promises and always returns an array of results, even if only one result
$.all = function (promises) {
    if (!Array.isArray(promises)) {
        throw new Error("$.all() must be passed an array of promises");
    }
    return $.when.apply($, promises).then(function () {
        // if single argument was expanded into multiple arguments, then put it back into an array
        // for consistency
        var args = Array.prototype.slice.call(arguments, 0);
        var returnVal;
        if (promises.length === 1 && arguments.length > 1) {
            // put arguments into an array for consistency
            returnVal = [args];
        } else {
            returnVal = args;
        }
        // now make Ajax results easier to use by making it be just an array of results, not an array of arrays
        // 
        return returnVal.map(function(item) {
            // see if this looks like the array of three values that jQuery.ajax() resolves to
            if (Array.isArray(item) && item.length === 3 && typeof item[2] === "object" && typeof item[2].done === "function") {
                // just the data
                return item[0];
            } else {
                return item;
            }
        });
    });
};

是的,根据文件,这正是应该发生的事情。您可以在
.when()
结果上使用
.then()
将结果变形为一致的结构。不,在使用jQuery的延迟系统时,没有办法解决这个问题。这就是它的工作原理,是的<代码>$。when()必须是整个jQuery中设计最差的API。我不再使用它了。我使用了
Promise.all()
。谢谢你的例子。这看起来是一个干净的解决办法。