使用Promise与async+await实现 异步请求(多个异步请求同时执行 或者多个异步请求按顺序一个执行完毕再到下一个)

基本使用

下面是 asyncPromise异步操作的基本使用。
使用场景:当异步操作需要按顺序执行时可以使用,如按顺序读取多个文件内容。
限制:await 后面表达式 异步出错了 会中断下一步的await 表达式的异步执行;

let asyncFn = async function() {
    
    
	await Promise.resolve('hello world 1').then(v => {
    
    
		console.log(v);
	});
	await Promise.resolve('hello world 2').then(v => {
    
    
		console.log(v);
	});
	await Promise.resolve('hello world 3').then(v => {
    
    
		console.log(v);
	});
}
asyncFn(); //hello world 1 hello world 2 hello world 3

出错例子

let asyncFn = async function() {
    
    
	await Promise.reject('出错了');
	await Promise.resolve('hello world').then(v => {
    
    
		console.log(v);
	});
}
asyncFn();

在这里插入图片描述
但是,如果使用了catch捕获错误,后面的异步可以继续执行;

let asyncFn = async function() {
    
    
	await Promise.reject('出错了').catch(e => {
    
    
		console.log(e);
	});
	await Promise.resolve('hello world').then(v => {
    
    
		console.log(v);
	});
}
asyncFn(); //出错了  hello world

如果需要捕获错误,对错误进行处理的同时中断下一步异步的执行,需要用到try...catch
await 放在 try...catch 里面,try...catch 捕获错误,Promise不要使用catch先行捕获

let asyncFn = async function() {
    
    
	try {
    
    
		await Promise.reject('出错了 1');
		await Promise.resolve('hello world').then(v => {
    
    
			console.log(v);
		});
		await Promise.reject('出错了 2');
	} catch (e) {
    
    
		console.log(e);
	}
}
asyncFn(); //出错了 1

当 使用场景是多个异步访问时,异步出错不中断下个await执行,如:批量导入数据;

下面是 续发:一个异步执行完毕之后再执行下一个异步的 执行’方式。这样做比较耗时,但可以防止高并发,防止线程阻塞,减少服务器压力;
try...catch
统一处理异步出错;

let asyncFn = async function() {
    
    
	for (var i = 0; i < 5; i++) {
    
    
		try {
    
    
			await Promise.reject('出错了');
		} catch (e) {
    
    
			console.log(e);
			}
	}

	await Promise.resolve('hello world').then(v => {
    
    
		console.log(v);
	});
}
asyncFn(); //出错了 出错了 出错了 出错了 出错了 hello world

Promise...catch
按需处理异步出错

let asyncFn = async function() {
    
    
	for (var i = 0; i < 5; i++) {
    
    
		await Promise.reject('出错了').catch(e => {
    
    
			console.log(e);
		});
	}

	await Promise.resolve('hello world').then(v => {
    
    
		console.log(v);
	});
}
asyncFn(); //出错了 出错了 出错了 出错了 出错了 hello world

当我们需要 同时触发:同时执行过个异步操作。服务器压力不大时,这样可以节省时间。

let nowDate1, nowDate2;
let asyncFn = async function() {
    
    

	await Promise.all([Promise1(), Promise2()])
	console.log('nowDate1-nowDate2', nowDate1 - nowDate2);
}

function Promise1() {
    
    
	return new Promise(function(resolve, reject) {
    
    
		setTimeout(() => {
    
    
			resolve();
		}, 3000);
	}).then(() => {
    
    
		nowDate1 = Date.parse(new Date())
		console.log('nowDate1', nowDate1);
	})
}

function Promise2() {
    
    
	return new Promise(function(resolve, reject) {
    
    
		setTimeout(() => {
    
    
			resolve();
		}, 1000);
	}).then(() => {
    
    
		nowDate2 = Date.parse(new Date())
		console.log('nowDate2', nowDate2);
	})
}
asyncFn(); 
//nowDate2 1608263144000
//nowDate1 1608263146000
//nowDate1-nowDate2 2000

从上面可以看出 两个异步的时间差是2000毫秒,而不是1000毫秒,说明两个异步是同时执行的;
Promise.all可以时同时触发异步请求;

 或者上例子的
await Promise.all([Promise1(), Promise2()])
改为
let fooPromise = Promise1();
let barPromise = Promise2();
let foo = await fooPromise;
let bar = await barPromise;
这样也会同时触发异步请求;

下面是一个 异步批量导入demo

// 防止高并发  一个请求完成后再执行下一个请求
const request = require('request');
let asyncFn = async function() {
    
    
	for (var i = 0; i < changeList.length; i++) {
    
    
		await putCompany(changeList[i], i);
	}
}
asyncFn();
function putCompany(item) {
    
    
	return new Promise(function(resolve, reject) {
    
    
		let requestData = {
    
    

		}
		request({
    
    
				url: URL + '/api/company',
				method: "PUT",
				json: true,
				headers: {
    
    
					"content-type": "application/json",
					'Authorization': Token,
				},
				body: item
			},
			function(err, response, body) {
    
    
				if (!err && (response.statusCode == 200 || response.statusCode == 204)) {
    
    
					resolve(body);
				} else {
    
    
					reject(err);
				}
			})
	}).then((res) => {
    
    
		if (res && res.content && res.content.length) {
    
    
			companyList = res.content;
		}
		console.log('putCompany res  修改成功!', res);
	}).catch((error) => {
    
    
		console.error('putCompany error ', index, error);
		errorList.push(item);
	});
};

猜你喜欢

转载自blog.csdn.net/weixin_43245095/article/details/111354368
今日推荐