【ECMAScript6】es6 要点(二)Promise | 自个写一个Promise | Generator | Async/Await

es6-promise.auto.js To use via a CDN include this in your html: <!-- Automatically provides/replaces `Promise` if missing or broken. --> [removed][removed] [removed][removed] <!-- Minified version of `es6-promise-auto` below. --> [removed][removed] [removed][removed] 立即下载

⭐️ 本文首发自 前端修罗场(点击加入),是一个由 资深开发者 独立运行 的专业技术社区,我专注 Web 技术、Web3、区块链、答疑解惑、面试辅导以及职业发展。博主创作的 《前端面试复习笔记》(点击订阅),广受好评,已帮助多人提升实力、拿到 offer。现在订阅,私聊我即可获取一次免费的模拟面试机会,帮你评估知识点的掌握程度,获得更全面的学习指导意见!

Promise:一种解决回调问题的技术

首先我们要理解同步与异步的含义:

  • 同步:函数在执行时会阻塞调用者,并在执行完毕后返回结果。
  • 异步:函数在执行时不会阻塞调用者,但是一旦执行完毕就会返回结果。例如,处理Ajax请求时就是在处理异步调用。

简言之:

  • 异步:操作之间没啥关系,同时进行多个操作

  • 同步:同时只能做一件事

  • 异步:代码更复杂

  • 同步:代码简单

Promise —消除异步操作,本质上是一个状态机

  • 当状态改变的时候,要调用之前挂起的then队列
  • then的时候直接执行对应的函数,并且要给参数
  • 用同步方式,书写异步代码

用法

let p = new Promise(function(resolve,reject){
	//异步代码
	//resolve --- 成功
	//reject ---  失败
	$.ajax({
		url:'arr.txt',
		dataType:'json',
		success(arr){
			resolve(arr);
		},
		error(err){
			reject(err);
		}
	});
	
});
//当有结果的时候就调用then
p.then(function(arr){//相当于resolve
	alert(arr);
},function(err){//相当于reject
	alert(err);
});

用 Promise 创建一个 getJSON

function getJSON(url) {
	return new Promise((resolve,reject)=>{
		const request = new XMLHttpRequest();//创建一个XMLHttpRequest对象
		request.open("GET",url);//初始化请求
		request.onload = function() {//注册一个onload方法,当服务器响应后被钓鱼那个
			try {
				if(this.status===200){
					resolve(JSON.parse(this.response));//尝试解析字符串
				}else {
					reject(this.status+" "+this.statusText);
				}
			}catch(e) {
				reject(e.message);
			}
		};

		request.onerror = function() {//和服务器通信发生错误
			reject(this.status+" "+this.statusText);
		};
		request.send();
	})
}
//调用
function handle() {
	const result1 = getJSON('a.json');
	result1.then(res=>{//回调成功返回
		console.log(res);
	}).catch(e=>{//回调发生错误
		console.log("Error:",e);
	});
}
// Promise.all
function handle() {
	const result1 = Promise.all([getJSON('a.json'),
		getJSON('b.json')]);
	result1.then(res=>{
		console.log(res); //返回一个数组
	}).catch(e=>{

	})
}
// Promise.race
function handle() {
	const result1 = Promise.race([getJSON('a.json'),
		getJSON('c.json')]);
	result1.then(res=>{
		console.log(res);//只会返回成功的第一个
	}).catch(e=>{

	})
}
//Async
async function handle() {
	try{
		const result1 = await getJSON('./statics/json/a.json');
		console.log(result1);
	}catch(e){
		console.log(e);
	}
}
handle()

用Promise封装fetch,FormData数据流方式

let data = {data1:data1,data2:data2};//使用json格式
let p = postData(url,data);
p.then(response=>{
	//响应结果代码逻辑
});
function postData(url,data) {
			let formData = new FormData();//将json转换成FormData数据流
			if(data instanceof Object){
				for(let i in data){formData.append(i, data[i]);}
			}
			return new Promise(function(resolve,reject){
				fetch(url,{
					method: 'POST',
					mode: 'cors',
					credentials: 'include',
					body:formData
				})
				.then(response => {
					return response.ok === true ? (response.json()) : reject({status:response.status});
				})
				.then(response => {
					resolve(response);
				})
				.catch(err => {
					console.log(err);
//					reject({status:-1});
				})
			})
		}
  • 基本使用
let p = new Promise(function(resolve,reject){
  setTimeout(function(){
     resolve(12);
  },500);
});
p.then(function(num){
		alert(num)
},function(error){
		alert(error);
});

多个Promise

  • Promise.all();
let p1 = new Promise(function(resolve,reject){
	//异步代码
	//resolve --- 成功
	//reject ---  失败
	$.ajax({
		url:'arr.txt',
		dataType:'json',
		success(arr){
			resolve(arr);
		},
		error(err){
			reject(err);
		}
	});
	
});
let p2 = new Promise(function(resolve,reject){
	//异步代码
	//resolve --- 成功
	//reject ---  失败
	$.ajax({
		url:'json.txt',
		dataType:'json',
		success(arr){
			resolve(arr);
		},
		error(err){
			reject(err);
		}
	});
	
});
//all(),Promise全都执行完之后
Promise.all([
	p1,p2
]).then(function(arr){
	alert('全都成功');
	let [res1,res2] = arr;
	alert(res1);
},function(err){
	alert('至少有一个失败')
});

简化:不写两个Promise

function createPromise(url){
	return new Promise(function(resolve,reject){
	//异步代码
	//resolve --- 成功
	//reject ---  失败
	$.ajax({
		url:url,
		dataType:'json',
		success(arr){
			resolve(arr);
		},
		error(err){
			reject(err);
		}
	});
	
});
}
Promise.all([
	createPromise('arr.txt'),
	createPromise('json.txt')
]).then(function(arr){
	alert(’全都成功‘);
	let [res1,res2] = arr;
	alert(res1);
},function(err){
	alert(’至少有一个失败‘)
});

结合jquery,高版本jquery自带Promise

Promise.all([
	$.ajax({url:'arr.txt',dataType:'json'}),
	$.ajax({url:'json.txt',dataType:'json'})
]).then(function(results){
	let [arr,json] = result;
},function(err){
	
});

其他用法

  • Promise.race 竞争,可以把它想象成赛马,每个函数都是一匹马,最快的那匹马会取得胜利。

同时如5个资源,哪个先来,先用哪个

Promise.race([
	$.ajax({url:'http://1.com'}),
	$.ajax({url:'http://2.com'}),
	$.ajax({url:'http://3.com'}),
])
Promise.all([
	$.ajax({url:'arr.txt',dataType:'json'}),
	$.ajax({url:'json.txt',dataType:'json'})
	$.ajax({url:'num.txt',dataType:'json'}),
	
]).then(results=>{
	let [arr,json,num] = results;
},err=>{
	console.log(err);
})

自个写一个Promise

class Promise {
	constructor(fn){
	  //重点
	  const _this =  this;
	  this.__queue = [];
	  this.__succ_res = null;
	  this.__erro_res = null;
	  this.status='';
	 fn(function(...arg){
	 	_this.__succ_res = arg;
	 	_this.status = 'succ';
	 	_this.__queue.forEach(json=>{
	 		json.fn1(...arg)
	 	});
	 },function(...arg){
	 	_this.__erro_res = arg;
	 	_this.status='error';
	 });
	}
	
	then(fn1,fn2){
	   if(this.status == 'succ'){
	   	fn1(...this.__succ_res)
	   }else if(this.status=='error'){
	      fn2(...this.__erro_res)
	   }else {
	      this.__queue.push({fn1,fn2})
	   }
	}
	all(arr) {
		let aResult= [];
		return new Promise(function(resolve,rject){
		  let i =0;
		  next();
		  function next(){
		   arr[i].then(function(res){
		     aResult.push(res);
		     i++;
		     if(i==arr.length){
		       resolve(aResult);
		     }else {
		       next();
		     }
		   },reject);
		  }
		})
	
	}
}

Generator

Generator不是一种函数式编程技术,但它是函数的一部分,因为函数式编程正是围绕着函数的技术。
我们前面提到,Promise是用于处理回调问题的技术,但是,随着ES6的发展与支持Generator,已经可以不需要Promise。

生成器,一种特殊类型的函数, 一种语法糖

  • 普通函数:一路到底
  • generator函数:中间能停

示例1

# 带星号:即在函数名称前使用一个星号来表示这是一个Generator函数。
function* show(){//创建一个generator对象
	alert('a');
	
	yield;//暂停
	
	alert('b');
}
let genObj = show(); //调用 Generator函数,生成一个迭代器,从而能够控制生成器的执行
console.log(genObj);//返回一个Generator原始类型的实例
genObj.next(); // 调用实例的next()函数,从Generator实例genObj中获取一个值,即:执行alert('a');
//如果再一次.next()就执行alert('b');


但是,我们不能无限制地调用next从Generator实例中获取值。否则最后会返回undefined。原因:Generator犹如一种序列,一旦序列中的值被消费,你就不能再次消费它。即,序列为空后,再次调用就会返回undefined!。

那么,要怎么能够才能再次消费呢?——需要另外再创建一个Generator实例。例如:
let genObj2 = show();

因此,迭代器用于控制生成器的执行,迭代器对象暴露的最基本接口是next方法。这个方法可以用来向生成器请求一个值,从而控制生成器。next函数被调用后,生成器就开始执行代码,当代码直行道yield关键字时,就会生成一个中间结果(生成值序列中的一项),然后返回一个新对象,其中封装了结果值(value)和一个指示完成的指示器(done)。
每当生成一个当前值后,生成器就会非阻塞地挂起执行,随后耐心等待下一次值请求鄂到达,这是普通函数完全不具备的特性。

Generator是如何转换的

示例2

 function* show(){
     let a = 12;
     let data1 = yield $.ajax('data/1.txt');
     
     let b = 5;
     let data2 = yield $.ajax('data/2.txt');
     return a+b;
  }
  //实际上,转换为:
  function show() {
     let a =12;
     $.ajax('data/1.txt').then(res=>{
        let data1 = res;
     })
     let b = 5;
     $.ajax('data/2.txt').then(res=>{
        let data2 = res;
        return a+b;
     })
  }

适合场景

  • 请求数据
  • 最大特点:让一个函数走走停停

重点:关键字 yield

yield 使Generator函数暂停了执行并将结果返回给调用者。第一次调用Generator实例时,yield将函数置于暂停模式并返回值。当下一次调用Generator实例时,Generator函数将从它中断的地方恢复执行。

用一段代码和对应的一张图演示Generator的操作序列:

function* genetatorSeq() {
	yield 'first';
	yield 'second';
	yield 'third';
}
let genSeq = genetatorSeq();
console.log(genSeq.next().value); //first
console.log(genSeq.next().value); //second
console.log(genSeq.next().value); //third

在这里插入图片描述
需要注意的是:所有带有yield的Generator都会以惰性求值的顺序执行。
何为惰性求值:

它指的是:代码直到调用时才会执行。即,当我们需要时,相应的值才会被计算并返回。

  • 可以传参和返回
function* show(num1,num2) {
	
	alert('a');
	let a =yield;
	alert('b');
	alert(a);//5
}
let gen = show(1,2);
gen.next(12);//没法给yeild传参
gen.next(5);//参数会被传递到
  • 返回
function* show() {
	alert('a');
	yield 12;
	alert('b');
	return 1;
}
let gen = show();
let res1= gen.next();
console.log(res1); 
//Obejct {value:12,done:false;}
let res2= gen.next(); 
console.log(res2);
//Object {value:1,done:true}
//value来自return,若没有return 则value为undefined
function* 炒菜(菜市场买回来的){
	洗菜->洗好的菜
	let 干净的菜= yeild 洗好的菜
	
	干净的菜->切菜->丝
	
	let 切好的菜 = yeild 丝;
	
	切好的菜->炒->熟的菜
	
	return 熟的菜;
}

done属性

每次对next函数调用,都将返回一个如下示例的对象:
{value:'value',done:false}
其中,

  • value来自Generator的值;
  • done是一个判断Generator序列是否已经被完全消费掉了的属性。当done的值为true时就应该停止调用Generator实例的next。

generator 实例

生成ID序列

function* countNum() {
	let i=0;
	while(true){
		yield ++i;
	}
}

const countGenerator = countNum();//生成一个迭代器
const obj1 = {
	id: countGenerator.next().value
}
const obj2 = {
	id: countGenerator.next().value
}
const obj3 = {
	id: countGenerator.next().value
}
console.log(obj1)
console.log(obj2)
console.log(obj3)
  • 处理异步操作

实例1

//httpGetAsync 通过node中的https模块触发一个Ajax调用以便获取响应
let https = require('https');
function httpGetAsync(url,callback) {
	return https.get(url,
		function(response) {
			let body = '';
			response.on('data',function(d) {
				body+=d;
			});
			response.on('end',function(d) {
				let parsed = JSON.parse(body);
				callback(parsed);
			});
	});
}
//request: 将httpGetAsync封装到一个单独的方法request中
function request(url) {
	httpGetAsync(url,function(response){
		generator.next(response);//用generator的next调用替换回调
	});
}
//main : 将业务需求封装到一个Generator函数内部
function* main() {
//调用yield将暂停函数执行,直到request通过接收Ajax的响应调用generator的next
	let json1 = yield request("https://www.reddit.com/r/pics/.json");
	let data1 = yield request(json1.data.children[0].data.url+".json")
	console.log(data1);
}
//运行
let gen = main();
gen.next();

实例2

cnpm i yield-runner-blue //获取文件夹中的index.js

数据读取

好处:像写同步操作一样写一步操作

runner(function* (){
	let data1 = yield $.ajax({url:'1.txt',dataType:'json'});//yield 出一个Promise对象给runner,然后执行返回给data1
	let data2 = yield $.ajax({url:'2.txt',dataType:'json'});
	let data3 = yield $.ajax({url:'3.txt',dataType:'json'});
	
	console.log(data1,data2,data3);
});

几种异步操作:

  • 回调
  • Promise
  • Generator

Generator对比Promise:

  • Promise 带逻辑
Promise.all([
	$.ajax({url:'getUserData',dataType:'json'})
]).then(results=>{
	let userData = results[0];
	if(userData.type=='vip'){
	   Promise.all([
	   	$.ajax({url:'getVipItems',dataType:'json'})
]).then(results=>{
	let items = results[0];
	//生成列表
},err=>{
	alert('fail');
})
	}
},err=>{
	alert('失败');
})

  • Generator 带逻辑
runner(function* (){
	let userData = yield $.ajax({url:'getUserData',dataType:'json'});
	if(userData.type=='vip'){
	let items = yield $.ajax({url:'getVipItems',dataType:'json'});
	}else {
	let items = yield $.ajax({url:'getItems',dataType:'json'});
	}
	//生成列表...
})

综上,generator适合处理逻辑性判断,Promise适合一次读一堆。另外,generator是对Promise一个封装。

用迭代器遍历DOM树

<body>
	<div id="subTree">
		<form>
			<input type="text" name="" />
		</form>
		<p>Paragraph</p>
		<span>Span</span>
	</div>
	<script type="text/javascript">
		function* DomTraversal(element){
			yield element;
			element = element.firstElementChild;
			while(element) {
				yield* DomTraversal(element); //用yield* 将迭代器控制器转移到另一个DomTraversal生成器实例上
				element = element.nextElementSibling;
			}
		}
		const subTree = document.getElementById("subTree");
		for(let element of DomTraversal(subTree)){//使用for-of 对节点进行循环迭代
			console.log(element)
		}
	</script>
</body>

Generator在KOA中的应用

https://koa.bootcss.com/

下载koa 与 koa-mysql

cnpm i koa
cnpm i koa-mysql
const koa = require('koa');//使用require引入koa库
const mysql = require('koa-mysql');

let db=mysql.createPool({host:'localhost',user:'root',password:'123456',dataBase
:'test'});//创建mysql

let server = new koa(); //创建一个服务

//generator在KOA中的应用
server.use(function *(){
	//this.body = 'abc';//在页面上输出abc
	let data = yield db.query('SELECT * FROM user_table');//查询user_table
	this.body = data;
});

server.listen(8080); //服务器监听

Generator 内部构造

调用一个生成器不会实际执行它。相反,它创建了一个新的迭代器,通过该迭代器我们才能从生成器中请求值。在生成器生成了一个之后,生成器会进入挂起执行并等待下一个请求到来的状态。从某种方面上说,生成器的工作更像一个状态机。

它分别有4种状态:

  • 挂起开始:创建一个生成器后,它最先以这种状态开始。其中的任何代码并没有执行。
  • 执行:生成器中的代码已开始执行。可能是刚开始执行,也可能是从上次挂起的时候继续执行。当生成器对应的迭代器调用了next()方法时,并且当前存在可执行的代码,生成器就会转移到这个状态。
  • 挂起让渡:当生成器在执行过程中遇到一个yield表达式,它会创建一个包含返回值的新对象,随后再挂起执行。生成器在这个状态暂停并等待继续执行。
  • 完成:在生成器执行期间,如果代码执行到return语句,或者全部代码执行完,生成器就会进入完成状态。

不同于标准函数,每次退出后就会销毁,生成器中,只要我们从生成器中取得控制权,生成器的执行环境上下文一直是保存的。

Generator和Promise结合

将生成器和Promise结合,能实现更加优雅的代码。例如:我们可以把异步任务放在生成器中,然后执行生成器函数。因为没法知道Promise什么时候会被resolved,所以生成器执行的时候,我们需要将执行权让渡给生成器,从而不会造成UI阻塞。当Promise被resolved,我们会继续通过迭代器的next函数执行生成器。

async(function* (){
	try {
		const a = yield getJSON('a.json');
		const b = yield getJSON('b.json');
		const c = yield getJSON('c.json');
	}catch(e){
		console.log("Error:",e);
	}
});
//辅助函数,对生成器执行操作
function async(generator) {
	let iterator = generator(); //创建一个迭代器,进而控制生成器

	function handle(iteratorResult) {//handle对生成器产生的每个值进行处理
		if(iteratorResult.done) {return;}//生成器没有结果时停止执行
		const iteratorValue = iteratorResult.value;
		if(iteratorValue instanceof Promise) {//如果生成器的值是一个Promise,则对其注册成功和失败回调
			//如果promise成功返回,则恢复生成器的执行并传入Promise的返回结果
			//遇到错误,向生成器抛出异常
			iteratorValue.then(res=>handle(iterator.next(res)))
						 .catch(err=>iterator.throw(err));
		}
	}
	try {
		handle(iterator.next());//重启生成器的执行
	}catch(e) {
		iterator.throw(e);
	}
}

由上述代码我们知道:

  • 函数是一等对象:向async函数传入函数参数
  • 生成器函数:它的特性可以用于挂起和恢复执行
  • Promise:帮助处理异步代码
  • 回调函数:在Promise对象上注册成功和失败的回调函数
  • 箭头函数:适合用在回调函数上
  • 闭包:迭代器在async函数内被创建,在promise的回调函数内通过闭包获取该迭代器

generator+promise 异步请求

function* exportGenerator(data){
    	let queryContent = "requestUrl";
    	let content = yield getJSON(queryContent)//返回一个Promise对象
    	return content;
}
let btn = docment.querySelector('.btn');
btn.addEventListener('click',function(){
	const exportInterator = exportGenerator();
	exportInterator.next().value.then(res=>{
		//todo List
	}).catch(e=>console.log("Error:",e));
})

//promise
function getJSON(url) {
		return new Promise((resolve,reject)=>{
			const request = new XMLHttpRequest();//创建一个XMLHttpRequest对象
			request.open("GET",url);//初始化请求
			request.onload = function() {//注册一个onload方法,当服务器响应后被钓鱼那个
				try {
					if(this.status===200){
						resolve(JSON.parse(this.response));//尝试解析字符串
					}else {
						reject(this.status+" "+this.statusText);
					}
				}catch(e) {
					reject(e.message);
				}
			};
	
			request.onerror = function() {//和服务器通信发生错误
				reject(this.status+" "+this.statusText);
			};
			request.send();
		})
	}
	

Async/Await

从上面看到,我们仍然要写一些样板代码。因为每次需要的时候都要复用,但如果不关心这个过程就好了!

通过在关键字function之前使用关键字async,可以表明当前的函数依赖一个异步返回的值,在每个调用异步任务的位置上,都要放置一个await关键字,用于告诉javascript引擎,请在不阻塞应用执行的情况下在这个位置上等待执行结果。

(async function(){
	try {
		const a = await getJSON('a.json');
		const b = await getJSON('b.json');
	}catch(e){
		console.log("Error:",e);
	}
})
ECMAScript Javascript Promise 详解 立即下载

相关推荐

5.1 Tessent Atpg系列 第八章 Test Pattern Generation - Verify Test Pattern

为什么要做基于timing的仿真,意义在于可以比较ATPG工具和simulator工具的差异性。因为时序的差异导致不同的结果。首先你需要通过write_patern 这句cmd来写出pattern,默认是parallel 模式,除非你用-serial 指定写出serial, 因为serial 文件非常大,所以你可以使用-sample 开关写出部分pattern即可,工具会根据每一种pattern 类型都会至少保存一只。 另外,你也可以使用-start -end 开关来减少文件大小,但是这样的截取,是不可靠的

ciscomonkey的博客 7759

关于ai流式生成报告,ios部分没反应,效果不显示的问题

求助

qq_20616053的博客 1222

41-dify案例分享-基于database插件实现Text2sql的数据库查询图表工作流

本文介绍基于 Text2SQL 的 Dify 工作流实现过程。先阐述 Text2SQL 概念、步骤及应用领域。接着说明工作流制作,包括用 chatflow 加开场白、获取系统时间,配置 LLM 生成 SQL,用 SQL Execute 工具查询,经 LLM 汇总结果,代码生成 ECharts 数据,条件分支判断图表类型输出。最后介绍验证测试、提供体验地址,还提及借助工具生成建表和初始化数据 SQL 语句。

个人技术 1万+

js加密解决方案1:在AutoJS中实现Promise的必要性、好处与缺点

AutoJS的加密代码限制了我们在脚本中直接使用ES6新特性,这可能会限制脚本的灵活性和功能。AutoJS的加密代码限制了我们在脚本中直接使用ES6新特性,这可能会限制脚本的灵活性和功能。然而,它的加密代码只支持ES5语法,不支持许多ES6的新特性,如Promise等功能。这个自定义的Promise简单地模拟了ES6 Promise的功能,使我们能够在ES5环境中使用类似的异步编程方式。这样,我们可以在AutoJS中编写更加高效、清晰的自动化脚本,提高脚本的可读性和可维护性。

mxd01848的博客 918

【JESD79-5之】11 IDD, IDDQ, IPP规格参数和测试条件(IDD, IDDQ, IPP Specification Parameters and Test conditions)

【代码】【JESD79-5之】11 IDD, IDDQ, IPP规格参数和测试条件(IDD, IDDQ, IPP Specification Parameters and Test conditions)

m0_61126667的博客 4855

【STM32系统】基于STM32+手机APP设计的智能停车场系统

功能简介1、进出停车场时需要刷卡,进行一个记时、计费的功能。2、停车位配有超声波检测,主要识别车位是否被占用。3、车位区域配有OLED显示屏,用户可以通过显示屏看到空闲车位。4、车位配有车位灯。当用户找不到车位可以通过手机点亮车位灯5、停车场配有温湿度检测和烟雾检测模块。当环境发生异常状态。会触动紧急报警。6、停车场信息会通过Wi-Fi发送数据上传至阿里云。用户可以通过手机了解到停车场空闲车位和停车时间、费用。

嵌入式阿齐Archie 2万+

unitTest(生成 HTMLTestRunner 模块)

一:生成 HTMLTestRunner 模块 unittest 里面是不能生成 html 格式报告的,需要导入一个第三方的模块:HTMLTestRunner 方法1.这个模块下载不能通过 pip 安装了,只能下载后手动导入,下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html 方法2.在 python 安装文件的 Lib 目录...

一个老宅男 913

2023年全国职业院校技能大赛“信息安全管理与评估”-真题——赛题题目+答案解析

2023年全国职业院校技能大赛“信息安全管理与评估”-真题——赛题题目+答案解析

君逍遥o 5987

获取流式输出内容示例(react)

实现一个能够通过流式API获取AI生成内容的页面,包含了加载状态显示、内容实时更新等功能,并采用了简洁现代的UI设计。内容会随着API响应逐步显示,直到完成后自动结束加载状态。

m0_59428422的博客 707

联邦学习中的差分隐私保护详解及python实现

随着数据隐私法规(如 GDPR、CCPA)日益严格,传统将数据集中到云端训练模型的方式面临合规与安全风险。联邦学习通过让各客户端保留本地数据,仅共享模型更新,缓解了数据流动带来的隐私风险。但模型更新仍可能泄露个体信息。为进一步保障隐私,可在本地更新中引入差分隐私(DP)机制,通过向梯度或模型更新中注入随机噪声,防止反向推断原始数据citeturn0search9。

闲人编程的博客 1919

进阶06:C#连接TwinCAT 3使用ADS通讯

本文介绍了使用C#通过ADS协议与倍福TwinCAT3 PLC通讯的实现方法。主要内容包括:1)在两台电脑上安装TwinCAT3开发环境并建立网络连接;2)在TwinCAT中定义变量和结构体;3)使用C# Winform开发界面,通过TwinCAT.Ads.dll实现读写功能;4)实现主动读取和通知两种数据获取方式。详细说明了连接建立、变量定义、读写操作及事件通知的实现代码。该方案实现了对PLC寄存器数据的实时监控和操作,为工业控制系统的开发提供了参考。

weixin_38637405的博客 3688

MyBatisGenerator:代码生成利器

在当今的软件开发领域,数据库与代码的同步管理是一个常见且重要的任务。随着项目的规模不断扩大,手动编写数据库表对应的实体类、映射文件以及SQL语句等变得异常繁琐,且容易出错。为了解决这一问题,MyBatisGenerator应运而生。MyBatisGenerator是一个基于MyBatis框架的代码生成器,它能够根据数据库表结构自动生成实体类、映射文件、SQL语句等代码。在大型项目中,手动编写这些代码不仅费时费力,而且容易出错,特别是在数据库结构发生变化时。

我是Java程序员廖志伟,感谢朋友们的支持!不定期贡献一篇高品质、过万文字、图文并茂且附有视频解说、满载代码示例注释的良心之作,坚决杜绝粗制乱造。 854

华为OD新系统机试真题 - 准备生日礼物(Py/Java/C/C++/Js/Go)

华为OD机试新系统真题 4.8【准备生日礼物】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【准备生日礼物】

qq_45776114的博客 1478

【React系列】ES6学习笔记(二)Promise、async\await

本文参考自电子书《ECMAScript 6 入门》:https://es6.ruanyifeng.com/ Promise 对象 1. Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。 所谓 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以

川峰的博客 2789

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

fast-element 响应式系统中的 PropertyChangeNotifier.unsubscribe():从 API 签名到观察者机制源码级解析

> 本文基于 @microsoft/fast-element 1.x 官方 API 参考页展开,深入讲解 `PropertyChangeNotifier.unsubscribe()` 方法的签名、参数语义与返回值,并结合 `packages/fast-element/src/observation/notifier.ts` 与 `notifier.pw.spec.ts` 中的实现与测试,剖析属性级

gitblog_00134的博客 489

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

如何快速掌握Async/Await:ECMAScript异步编程的完整入门教程

Async/Await是ECMAScript提供的异步编程语法糖,它建立在Promise基础之上,让开发者能够用同步的方式编写异步代码。本教程将帮助你快速理解并掌握这一强大特性,告别回调地狱,写出更清晰、更易维护的JavaScript异步逻辑。 ## 🚀 为什么选择Async/Await? 在Async/Await出现之前,JavaScript异步编程主要依赖回调函数和Promise。虽然P

gitblog_00748的博客 432

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Jupytext 的 Pandoc Markdown 格式实战:Raw Cell 与 `.cell` 语法完全解析

Jupytext 提供了一种特殊的 Pandoc Markdown 文本格式(`md:pandoc`),它借助 Pandoc 自身的能力将 Jupyter Notebook 双向转换为结构化的 Markdown 文档。本文以仓库中 `tests/data/notebooks/outputs/ipynb_to_pandoc/` 目录下的真实测试样本为主线,深入讲解 Pandoc 格式的 YAML 头

gitblog_01106的博客 384

ES6的Promise和Generator的解读

Generator 是实现JavaScript 迭代协议最简单的方式。任何定义了方法的对象都是可迭代的,可以被for...of循环遍历。而 Generator 函数默认就返回一个迭代器。yield 1;yield 2;yield 3;// for...of 循环会自动调用 .next(),直到 done 为 true// 输出:// 1// 2// 3// 也可以轻松创建一个无限序列的生成器let id = 1;yield id++;// 1// 2// 3是什么。

chaoxxggg的博客 1047

js - generator 和 async 函数讲解

摘要 ES6引入了Generator函数作为异步编程的新方案,相比回调函数和Promise具有独特优势。Generator函数通过yield表达式实现暂停执行,需要调用next()方法逐步执行,返回包含value和done属性的对象。其特点包括:function后加*号定义、返回指针对象、分阶段执行。async/await是Generator的语法糖,改进在于内置执行器、更好语义、更广适用性和返回Promise对象,使异步代码更接近同步写法,成为现代JavaScript异步编程的主流方案。

尽日寻春不见春,芒鞋踏遍陇头云。归来笑拈梅花嗅,春在枝头已十分。 761

ES6 - generator和async函数

ES6 引入了 Generator 函数和 async/await 语法糖来改进异步编程。Generator 通过 yield 暂停执行和 next 恢复执行,解决了回调地狱问题,但需要手动调用 next。async/await 基于 Generator 实现,用 async 替代 *,await 替代 yield,具有自动执行器、更清晰的语义和返回 Promise 等优势,使异步代码更接近同步写法。这两种方式都大幅提升了异步代码的可读性和可维护性。

尽日寻春不见春,芒鞋踏遍陇头云。归来笑拈梅花嗅,春在枝头已十分。 541

[ES6]Day11—Promise的使用、Async/await 的使用

1. Promise 的定义 Promise 是一个对象,它代表了一个异步操作的最终完成或者失败。 2. Promise 的使用 本质上Promise是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。 以 createAudioFileAsync() 为例 // 成功的回调函数 function successCallback(res...

iChangebaobao的博客 360

ECMAScript Async/Await向后兼容性:如何优雅降级支持旧浏览器

Async/Await是ECMAScript中处理异步操作的强大特性,它让异步代码看起来像同步代码一样直观。然而,在实际开发中,我们经常需要面对旧浏览器不支持这一特性的问题。本文将详细介绍如何实现Async/Await的优雅降级,确保你的代码在各种浏览器环境中都能正常运行。 ## 为什么需要考虑向后兼容性 尽管现代浏览器已经广泛支持Async/Await特性,但在一些企业环境或特定用户群体中,

gitblog_00212的博客 336

ECMAScript Async/Await社区生态:工具、库和最佳实践大全

ECMAScript的Async/Await特性彻底改变了JavaScript异步编程的方式,让开发者能够以同步代码的形式编写异步逻辑。本文将全面介绍Async/Await的社区生态,包括实用工具、优质库和经过验证的最佳实践,帮助你轻松掌握这一强大特性。 ## 一、Async/Await基础:为什么它如此重要 Async/Await是ECMAScript标准中基于Promise和生成器的异步编

gitblog_00326的博客 443

generative-models 文生图、图生视频与3D环绕全链路指南:权重下载到首次跑通只要10分钟

首次跑 Stability AI 的 generative-models,最常见的失败现场是:权重明明下完了,脚本却报 `FileNotFoundError`;或者文件只有几百字节,一加载就崩。本文覆盖文生图、图生视频、3D环绕的下载、环境、首跑全链路,照做约10分钟出第一段视频。 ## 👥 这篇文章给谁看 这个仓库是 Stability AI 官方生成模型代码库,文生图(SDXL / SD

gitblog_00449的博客 394

ECMAScript6(0):ES6简明参考手册

在ES6中,我们一种更简洁的实现方法:模板字面量(Template Literals)(译注:原文是Template Literals,而非Template Strings)利用模板字面量,我们可以直接在字符串使用特殊字符而不用转义它们。let text =;模板字面量还支持插值,可以轻松完成连接字符串和值的任务:在ES5中,我们这样操作多行字符串:‘cat\n’ +‘dog\n’ +或者‘cat’,‘dog’,

2501_90252505的博客 882

OpenChamber 1.19.0 版本解读:Claude 用量限额、Project Knowledge 与集成管理

> 本文基于仓库 [changelog/1.19.0.md](https://link.gitcode.com/i/98eebe825c0f0f8a5c31d1413056ea8c) 的发布说明展开,并结合 [packages/web/server/lib/quota/DOCUMENTATION.md](https://link.gitcode.com/i/49113fcade5d2e3676d5

gitblog_00962的博客 793
上一篇: 【ECMAScript6】es6 要点(一)剩余参数 | 数组方法 | 解构赋值 | 字符串模板 | 面向对象 | 模块
下一篇: 面向征信的区块链模式设计与应用研究
蟹蟹蟹风流
蟹蟹蟹风流 优质创作者: 编程框架技术领域 优质创作者: 编程框架技术领域 领域专家: 前端开发技术领域 领域专家: 前端开发技术领域
博客等级 码龄11年 3万+粉丝 396原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蟹蟹蟹风流

期望和你分享一杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值