<!doctype html> <html lang="zh"> <head> <meta charset="utf-8"> <title>使用Deferred解决回调问题</title> </head> <body> <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js"></script> <script type="text/javascript"> let deferred1 = $.Deferred(); // 第1个Deferred对象 let deferred2 = $.Deferred(); // 第2个Deferred对象 let deferred3 = $.Deferred(); // 第3个Deferred对象 // 这里是异步的,必须三个Deferred对象都调用了resolve()才会执行done() $.when(deferred1, deferred2, deferred3).done(function(name, gender, age) { console.log('俺叫' + name + '(' + gender + '),今年' + age + '岁。'); // 俺叫张三(男),今年18岁。 }); // 这里顺序无所谓,但是只要还有一个Deferred对象没有调用resolve()就不会执行上面设置的done() deferred3.resolve(18); // 第3个Deferred对象调用resolve() deferred1.resolve('张三'); // 第1个Deferred对象调用resolve() deferred2.resolve('男'); // 第2个Deferred对象调用resolve() //========== 总结 ==========// // 1、当所有Deferred对象都调用了resolve()后就会立即执行done()。 </script> </body> </html>
<!doctype html> <html lang="zh"> <head> <meta charset="utf-8"> <title>图片加载完成后回调</title> <style type="text/css"> *{margin:0;padding:0;} li{float:left;display:block;margin:10px;list-style:none;} img{width:250px;height:auto;} </style> </head> <body> <ul> <li><img src="https://gd-hbimg.huaban.com/0baaa30f2c64c01aa7a9282c9aba829b7eaf35c24332a-tzFLxo_fw1200webp" alt=""></li> <li><img src="https://gd-hbimg.huaban.com/0f5627cb52d09630555c6984fcdbba413bc19ed3780aa-GuY8C8_fw1200webp" alt=""></li> <li><img src="https://gd-hbimg.huaban.com/1a86098a1b012bf28b88843fff46441c56c8b0b4a47c3-uXHCKe_fw1200webp" alt=""></li> <li><img src="https://gd-hbimg.huaban.com/1e589bbbc0a18988d6ad6323767b1beba5d26a68ae077-0wUf0V_fw1200webp" alt=""></li> <li><img src="https://gd-hbimg.huaban.com/3e8b142316fa139244c592d3582dab216d243d882734c-94KnbB_fw1200webp" alt=""></li> <li><img src="https://gd-hbimg.huaban.com/42b80c9cf61edaa6d73b91faee7302ab0b059f8c1b8a3-ZGvvD4_fw1200webp" alt=""></li> <li><img src="https://gd-hbimg.huaban.com/43a4ba5ae2bc8d454f94de14d8e825cd20fdfb4adf8b8-5ReQvh_fw1200webp" alt=""></li> </ul> <script type="text/javascript" src="./jquery.min.js"></script> <script type="text/javascript"> let imgs = $('ul > li > img'); // 所有图片 let deferreds = []; // Deferred对象 // 通过延迟执行可以模拟出一部分图片在绑定load和error事件前已经完成加载的情况 setTimeout(function () { // 遍历所有图片 imgs.each(function () { // 对尚未完成加载(注:这里的完成包括加载成功和加载失败)的图片绑定load和error事件 if (!$(this).get(0).complete) { let def = $.Deferred(); $(this).on('load', function () { // 加载成功 console.log('load + 1 ', Math.random()); def.resolve(); }).on('error', function () { // 加载失败 console.log('error + 1 ', Math.random()); def.resolve(); }); deferreds.push(def); } }); // 这里是异步的,必须等deferreds里所有的Deferred对象都调用了resolve()才会执行 $.when.apply(null, deferreds).done(function () { console.log('所有图片加载完成'); }); }, 150); //========== 输出结果·开始 ========== // load + 1 0.38514296932924075 // load + 1 0.5667542539732484 // load + 1 0.8111099284922989 // 所有图片加载完成 //========== 输出结果·结束 ========== //========== 总结 ==========// // 1、可以通过开发者工具限制网速,这样能更直观地看到加载流程是怎么样的。 // 2、虽然图片有7张,但是由于代码延迟执行的原因,有些图片在执行到遍历所有图片时就已经加载完成了,这部分图片的complete属性为true所以 // 不会执行到绑定load和error事件的代码,所以输出结果只有三个“load + 1”,事实上就算绑定了也没意义,因为已经加载完成的图片是不会 // 再触发load事件的。 </script> </body> </html>
Copyright © 2024 码农人生. All Rights Reserved