javascript - 在嵌套循环中从 $.get() 返回数组

标签 javascript jquery json asynchronous

我正在编写一个 jQuery 插件,它接受一组 json 文件,然后我需要将其编译成一个大数组。

到目前为止,代码的不同部分都可以独立工作,但是一旦我将它们放在一起,我就无法返回新数组。

我假设要么是我不理解如何从嵌套循环返回值,要么是 $.get() 是异步的而 $.each() 循环是异步的问题>同步。或者可能是两者的混合。

我尝试过使用 jQuery $.Deferred 但没有运气。任何有关如何解决此问题的指示都是受欢迎的。

这是目前的插件代码。我已经对代码进行了注释,因此应该很“容易”地看到我正在尝试做什么:

(function ( $ ) {
 
    $.fn.presspull = function( options ) {
 
        // This is the defaults settings which can be changed via the plugin call.
        var settings = $.extend({
            // These are the defaults.
            template	: 	Handlebars.compile( $('#pressTemplate').html() ),
            placeHolder : 	$("#press-grid"),
            addMoreBtn	: 	$("a#press-show-more"),
            segment 	: 	4,
            dataSource 	: 	[]
             
        }, options ); // end settings

        // non mutable elements which can not be changed from the plugin call.
        var cache = {
        		pressArray	: new Array(),
        		compileCount: 0,
        		segmentItt	: 0
        }; // end cache

/*============================================================================
  – Compile Source: function to build and sort the combined press.
==============================================================================*/

        function compileSource() {
        	// check if the data source contains anything.
        	if ( settings.dataSource.length > 0 ) { 
        		// for each json file in the data source do...
	        	$.each( settings.dataSource , function( k, v ) {
	        		// get the data 
	        		$.get( v, function( data, status, xhr ){
	        			// next loop through the output
	        			$.each( data, function( i, e ){
	        				// add each entry to the pressArray
	        				cache.pressArray.push( e );
	        			}); // end each
	        		// once done do..
	        		}).done( function() {
	        			// compile count increments for every data source
						cache.compileCount ++;
						if ( cache.compileCount == settings.dataSource.length ) { 

							cache.pressArray.sort( function( a, b ) {
								var c = new Date(a.date),
									d = new Date(b.date);
					
								return c>d ? -1 : c<d ? 1 : 0;
							}); // end sort

							// after compiling and sorting the new list we return it.

						}; // end if
					// if there is a failure in getting the data it's logged as following     			
	        		}).fail( function() {
    					console.log("Failed to get data from: " + v );
  					}); // end get.done
	        	}); // end each
        	} else {
        		console.log("Source files not found!");
        	};

        	return console.log( cache.pressArray);
        }; // end compileSource

 
    }; // end $.fn.presspull
 
}( jQuery ));

json 文件如下所示:

[
      {
            "publication": "Dazed & Confused",
            "date": "2013-05-01",
            "region": "UK",
            "cover": "{{ 'img-press-cover-dazed-2013.png' | asset_url }}",
            "pressmedia": [
                  {
                  "name":"soma",
                  "image": "Document Name 1 - General",
                  "description": "description for image 1",
                  "keyproduct": "link to the key product on the image"
                  },
                  {
                  "name":"soma2222",
                  "image": "Document Name 2 - General",
                  "description": "description for image 1",
                  "keyproduct": "link to the key product on the image"
                  }

            ]

]

插件调用如下:

$().presspull({
      dataSource   :   [
      "http://link/to/external/json/file/01",
      "http://link/to/external/json/file/02",
      "http://link/to/external/json/file/03"
      ]
});

最佳答案

这里的问题是你的方法 compileSource 是异步的,这意味着当你尝试从该方法返回数组时,ajax 内容不会完成,因此你将得到一个空数组。

解决方案是使用回调

    function compileSource(callback) {
        // check if the data source contains anything.
        if ( settings.dataSource.length > 0 ) { 
            // for each json file in the data source do...
            $.each( settings.dataSource , function( k, v ) {
                // get the data 
                $.get( v, function( data, status, xhr ){
                    // next loop through the output
                    $.each( data, function( i, e ){
                        // add each entry to the pressArray
                        cache.pressArray.push( e );
                    }); // end each
                // once done do..
                }).done( function() {
                    // compile count increments for every data source
                    cache.compileCount ++;
                    if ( cache.compileCount == settings.dataSource.length ) { 

                        cache.pressArray.sort( function( a, b ) {
                            var c = new Date(a.date),
                                d = new Date(b.date);

                            return c>d ? -1 : c<d ? 1 : 0;
                        }); // end sort

                        callback(cache.pressArray)

                        // after compiling and sorting the new list we return it.

                    }; // end if
                // if there is a failure in getting the data it's logged as following               
                }).fail( function() {
                    console.log("Failed to get data from: " + v );
                }); // end get.done
            }); // end each
        } else {
            console.log("Source files not found!");
        };
    }; // end compileSource

    //call the compile method
    compileSource(function(array){
        //this function will be called once all the data is received and sorted, the sorted array will be passed as an argument
    })

关于javascript - 在嵌套循环中从 $.get() 返回数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29470240/

相关文章:

javascript - 简化两个 jQuery 函数以更改两个单独下拉菜单的背景

javascript - 有没有办法在 JavaScript 中反转 Intl.NumberFormat 的格式

javascript - JS : Check Input Box In a certain TD

javascript - 表单验证在 jQuery 中不起作用

javascript - 如何根据页面位置实现 ng-show

javascript - 将对象推送到数组并使用另一个对象作为属性

javascript - 从 osm 立交桥 API 读取和分析 JSON - 获取折线

javascript - 获取div的父级的父级

javascript - 连接变量+选择器

javascript - Ember.js/Rails 将关系发布到 Rails