简体   繁体   English

使用map / reduce和jQuery顺序运行任意数量的脚本

[英]Run an arbitrary number of scripts sequentially using map/reduce and jQuery

I need to run an arbitrary number of scripts. 我需要运行任意数量的脚本。 The next one can run only of the previous has loaded and executed. 下一个只能运行已加载并执行的前一个。 I know RequireJS (and related) would be the correct choice, but I'm trying to learn about promises, so this is my experiment: 我知道RequireJS(及相关)会是正确的选择,但是我正在尝试了解Promise,所以这是我的实验:

var files = [
  'first.js',
  'second.js',
  'third.js',
  'fourth.js'
];

var funcs = files.map(function(file) {
  return function() { return $.getScript(file); }
});

var deferred = $.Deferred();

funcs.reduce(function (soFar, f) {
   return soFar.then(f);
}, deferred.resolve(funcs[0])); 

Can someone elaborate about the pitfalls and alternatives to my solution? 有人可以详细说明我的解决方案的陷阱和替代方法吗?

What you're really looking for is .pipe ( or in 1.8+, I believe .then was changed to mean the same thing ) 您真正想要的是.pipe (或者在1.8+中,我相信.then被更改为相同的意思)

In short, pipe will allow you to chain promises in the way that you're looking for. 简而言之,管道将使您能够以所需的方式链接承诺。 The code might look something like this ( untested ): 代码可能看起来像这样(未经测试):

var files, scriptsLoaded;

files = [ 'first.js', 'second.js', 'third.js', 'fourth.js' ];

while( files.length ) {
    (function() {
        var currentUrl = files.shift();

        scriptsLoaded = scriptsLoaded ?
            scriptsLoaded.pipe(function() {
                return $.getScript( currentUrl );
            }) :
            $.getScript( currentUrl );
    }());
}

$.when( scriptsLoaded ).done(function() {
    // All scripts are now loaded assuming none of them failed
});

** Edit ** **编辑**

With that link you provided, I understand what you were trying to accomplish. 通过您提供的链接,我了解您要完成的工作。 Here's a corrected version of your solution with some comments. 这是带有一些评论的解决方案的更正版本。 It accomplishes the same thing as the other solution, however it's a much more concise version: 它实现了与其他解决方案相同的功能,但是它是一个更为简洁的版本:

var files = [ 'first.js', 'second.js', 'third.js', 'fourth.js' ];

// The initial value provided to the reduce function is a promise
// that will resolve when the first file has been loaded.  For each
// of the remaining file names in the array, pipe it through that first
// promise so that the files are loaded in sequence ( chained ).
// The value that is returned from the reduce function is a promise
// that will resolve only when the entire chain is done loading.
var scriptsLoaded = files.slice(1).reduce(function (soFar, file) {
    return soFar.pipe(function() {
        return $.getScript( file );
    });
}, $.getScript( files[0] ); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM