js之Promise异步操作管理者

Promise

1.处理异步操作,避免回调地狱(大量的回调函数调用),是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
2.ES6的Promise是一个构造函数, 用来生成Promise实例, Promise实例是异步操作管理者。
3.Promise代表了未来某个将要发生的事件(通常是一个异步操作) 有了Promise对象, 可以将异步操作以同步的流程表达出来, 避免了层层嵌套的回调函数(俗称’回调地狱’)。
4.Promise为了取代回调函数。
Promise一共有3个状态, 和执行顺序

  1. pending: 初始化状态
  2. fulfilled: 成功状态
  3. rejected: 失败状态

new Promise时, 回调函数马上执行, 而异步任务则是通过回调

let promiseObj = new Promise((resolve, reject) => {
    
     // pending(初始化状态)
	console.log('promise刚开始'); // 同步执行
	setTimeout(function () {
    
     // 启动异步任务
		console.log('异步任务操作成功');
		resolve('请求成功了'); // pending----> fulfilled(成功状态)
     	// reject('请求超时了'); // pending----->rejected (失败状态)
    }, 2000)
});

promiseObj.then(data => {
    
    
	console.log(data);
}).catch(err => {
    
    
	console.error(err);
});
console.log('主线程执行-------');

回调地狱案例
在第一个接口请求成功后,继续请求第二个接口…

$.ajax({
    
    
	url: "接口地址",
	type: "POST",
	dataType: "json",
	success(res) {
    
    
		$.ajax({
    
    
			url: `接口地址`,
			data: {
    
    
				firstId: res['data'][2]['first_id']
			},
			type: "POST",
			dataType: "json",
			success(res2) {
    
    
				$.ajax({
    
    
					url: `接口地址`,
					data: {
    
    
						secondId: res2['data'][0]['second_id']
					},
					type: "POST",
					dataType: "json",
					success(res3) {
    
    
						$.ajax({
    
    
							url: `接口地址`,
							data: {
    
    
								thiredId: res3['data'][0]['thired_id']
							},
							type: "POST",
							dataType: "json",
							success(result) {
    
    
								console.log(result);
							}
						})
					}
				})
			}
		})
	}
})

改写成Promise配合下面async+await改写成同步的

async function(){
    
    
	const res = await myAjax("/one")
	const res2 = await myAjax("/two");
	const result = await myAjax("/three");
}
// 注意;  (myAjax内使用Promise没有贴出来)

使用

1.创建Promise对象, 返回结果

let promise = new Promise((resolve, reject) => {
    
     // 生成Promise对象, 包含异步操作
	setTimeout(()=>{
    
     // 异步操作, 返回结果
		resolve("成功返回"); 
		// reject("报错返回");
	}, 2000);
});

2.调用then方法, 接收异步–成功结果

promise.then(data => {
    
     // 使用then方法接收 异步成功的结果
    console.log(data); 
})

3.调用catch方法, 接收异步–报错结果

promise.then(data => {
    
     // 使用then方法接收 异步成功的结果
    console.log(data); 
}).catch(err => {
    
      // 使用catch方法接收 异步报错的结果
	console.error(err);
})

4.链式调用then方法, then里return会返回一个Promise对象

promise.then(data => {
    
     
    return "链式调用";
}).then(res => {
    
    
	console.log(res);
})

使用promise async await 封装ajax请求

function getNews(url) {
    
    
    return new Promise((resolve, reject) => {
    
      // 创建一个promise对象, 并返回
        $.ajax({
    
    
            url,
            type: 'GET',
            success: data =>  resolve(data),
            error: error => reject(error)
        })
    })
}
getNews('https://cnodejs.org/api/v1/topics').then((news) => {
    
    
    document.body.innerHTML = news['data'].reduce((str, obj) => {
    
    
        return str += `<h4>${
      
      obj['title']}</h4>`
    }, "");
})

Promise.all

作用: 可以用于把多个Promise对象合并成 一个大的promise对象使用

案例: 获取3个一级分类下所属的二级分类数据

url: 地址 one two three

// 如果每次调用一个Promise对象, 用then每个来分别接收ajax回来的数据
// 注意: 顺序不对, 而且谁先回来不一定, 3个回调, 没法等待同一时间返回
// 引出, Promise.all() 会根据数组的顺序, 把返回的Promise.all的数据按照数组的顺序组织返回
        Promise.all([one, two, three]).then(res => {
    
    
            console.log(res);
        }).catch(err => {
    
    
            console.error(err);
        })

// 注意, 这一组promise对象, 有一个触发了失败reject, 那么then不会执行

猜你喜欢

转载自blog.csdn.net/qq_43291759/article/details/108867440