0
回答
一次 JavaScript闭包的实例应用
滴滴云服务器,限时包月0.9元,为开发者而生>>>   

以下是杰表打印控件获取打印机及打印机状态的两端代码片段,代码片段一种存在一个bug,就是可以显示打印机,但无法显示打印机状态。debug代码后发现,代码片段一种i的值在getPrinterStatus方法回调中始终等于printers.length,这是为什么呢?

第一:getPrinterStatus方法是异步的。第二:i变量处在getPrinterStatus方法外的上下文中。也就是没等getPrinterStatus方法执行完,i的值已经被外部改变,自然就得不到想要的值。

这个时候用闭包就能很好的解决这个问题,如代码片段二所示,把for循环中调用异步方法的代码用闭包封装起来,给每个i一个独立的上下文就能解决这个问题了。

代码片段一:

getJatoolsPrinter().getDefaultPrinter(function (defaultPrinter) {
						  getJatoolsPrinter().getPrinters(function (printers) {
							  for (var i = 0; i < printers.length; i++) {
								  // 此处一定要用闭包封装,否则getJatoolsPrinter().getPrinterStatus使用的外部变量会达不到预期,如i会一直等于printers.length
								  var printer = printers[i];
								  var printerText = printers[i];
								  getJatoolsPrinter().getPrinterStatus(printer, false, function (result) {
									  printerText = printerText + "【状态:" + result + "】"; // 显示的打印机选择文本,加了打印机的状态
									  if (defaultPrinter == printer) {
										  printServiceHtml += ("<option value='" + printer + "' selected>" + printerText + "</option>");
									  } else {
										  printServiceHtml += ("<option value='" + printer + "'>" + printerText + "</option>");
									  }
									  if (i == printers.length - 1) {
										  if (printServiceHtml) {
											  printServiceHtml = "<select id='selectPrintService'>" + printServiceHtml + "</select>";
										  }
										  if (!printServiceHtml) {
											  common.dialogError("没有找到打印服务,请确认打印机连接是否正常!");
										  } else {
											  doPrintSettlementNew(printServiceHtml, previewTagTmp, param);
										  }
									  }
								  });
							  }
						  });
					  });

 

代码片段二:

getJatoolsPrinter().getDefaultPrinter(function (defaultPrinter) {
						  getJatoolsPrinter().getPrinters(function (printers) {
							  for (var i = 0; i < printers.length; i++) {
								  (function () {
									  // 此处一定要用闭包封装,否则getJatoolsPrinter().getPrinterStatus使用的外部变量会达不到预期,如i会一直等于printers.length
									  var innerI = i;
									  var printer = printers[innerI];
									  var printerText = printers[innerI];
									  getJatoolsPrinter().getPrinterStatus(printer, false, function (result) {
										  printerText = printerText + "【状态:" + result + "】"; // 显示的打印机选择文本,加了打印机的状态
										  if (defaultPrinter == printer) {
											  printServiceHtml += ("<option value='" + printer + "' selected>" + printerText + "</option>");
										  } else {
											  printServiceHtml += ("<option value='" + printer + "'>" + printerText + "</option>");
										  }
										  if (innerI == printers.length - 1) {
											  if (printServiceHtml) {
												  printServiceHtml = "<select id='selectPrintService'>" + printServiceHtml + "</select>";
											  }
											  if (!printServiceHtml) {
												  common.dialogError("没有找到打印服务,请确认打印机连接是否正常!");
											  } else {
												  doPrintSettlementNew(printServiceHtml, previewTagTmp, param);
											  }
										  }
									  });
								  })();
							  }
						  });
					  });

 

<无标签>
举报
学而不思则罔
发帖于11个月前 0回/219阅
顶部