Promise 上手

Promise 上手

Promise是抽象异步处理对象以及对其进行各种操作的组件。promise的功能是可以将复杂的异步处理轻松地进行模式化。

1.Promise基础结构

Promise是一个对象,而非函数,对象的好处就是可以状态不受外界影响,并保存一些回调状态信息。

new Promise(function)

Promise的构造函数要求传入一个函数,当Promise被创建的时候,Promise会执行传入的函数。传入的函数有两个参数resolve, reject,分别对应异步成功和异步失败。

new Promise(function(resolve, reject) {
    setTimeout(()=>{
        console.log('异步操作');
	},1000)
})

当函数中的异步操作执行成功后,调用resolve进行相应的处理,resolve是用于执行回调函数,可以通过resolve将异步操作(一般是异步请求)得到的数据传递到resolve里面。

new Promise(function(resolve, reject) {
    setTimeout(()=>{
        console.log('异步操作');
        resolve('通过参数进行信息的传递')
	},1000)
})

resolve()回调放在了then里面,reject()可以放在then中也可以放在catch中,后面会介绍。

var promise = new Promise(function(resolve, reject) {
	//异步请求,假设请求回来的数据为data
    if(data != null){
        //调用resolve
        resolve(data)
    }else{
        //调用reject
        reject('请求失败')
    }  	
})

//通过then来设置resolve要执行的回调函数
promise.then(data => {
    console.log(data);   //在控制台中打印刚刚resolve传递过来的data
})
//通过catch来设置reject要执行的回调函数
promise.catch(data => {
    console.log(data);   //在控制台中打印刚刚resolve传递过来的data
})
为什么用promise?

当一些为了请求需要多层嵌套的时候,如果使用的是Ajax,那么就会出现回调地狱的情况,回调地狱可以简单地认为过多的异步请求的嵌套,导致一堆回调函数的嵌套,从而导致代码结构复杂,层次不鲜明,不易于管理。而promise是一个对象,他提供了链式编程,可以不受外界影响通过对象来管理回调函数,层次鲜明,易于维护。

2.promise基础用法

promise用的是链式编程,下面就写了promise的基本用法。

  • 第一种:异步成功调用resolve(),调用resolve()后将会异步执行then()中的回调函数,失败则调用reject(),调用reject()执行 的是catch()里面的回调函数。
  • 第二种:将异步成功和失败都写在then(onFulfilled, onRejected)里面,onFulfilled代表成功回调,onRejected失败回调。
var promise = new Promise(function(resolve, reject) {
    // 异步处理
    // 处理结束后、异步处理成功调用resolve 或 失败调用reject
    resolve()
}).then(()=>{
    //调用resolve()后,要执行的回调操作
}).catch(()=>{
    //调用reject()后,要执行的回调操作
});


//-----------------------------------------------
//或者这样使用
var promise = new Promise(function(resolve, reject) {
    // 异步处理
    // 处理结束后、异步处理成功调用resolve 或 失败调用reject
    resolve()
});
//promise.then(onFulfilled, onRejected)
promise.then((data)=>{
    //调用resolve()后,要执行的回调操作,onFulfilled被调用
},(err)=>{
    //调用reject()后,要执行的回调操作,onRejected被调用
})

3.使用示例

用.then(onFulfilled).catch(onRejected)方式

new Promise((resolve,reject) =>{
	setTimeout(()=>{
        console.log('干了一些处理');
		resolve('异步执行成功的回调')
	},1000)
}).then((data)=>{
	console.log(data);   //异步成功的回调
}).catch((err)=>{
    console.log(err);    //异步失败的回调
});

用.then(onFulfilled, onRejected)方式

new Promise((resolve,reject) =>{
	setTimeout(()=>{
		resolve('异步执行成功的回调')
	},1000)
}).then((data)=>{
	console.log(data);   //异步成功的回调
},(err)=>{
    console.log(err);    //异步失败的回调
});

模仿网络请求

new Promise(function (resolve, reject) {
        var req = new XMLHttpRequest();
        req.open('GET', URL, true);
        req.onload = function () {
            if (req.status === 200) {
                resolve(req.responseText);
            } else {
                reject(new Error(req.statusText));
            }
        };
        req.onerror = function () {
            reject(new Error(req.statusText));
        };
        req.send();
}).then(function onFulfilled(value){
    console.log(value);
}).catch(function onRejected(error){
    console.error(error);
});

4.promise的状态(了解)

promise有三种状态:

  • pending:等待状态
  • fulfill:满足状态,调用resolve(),回调.then()中的函数
  • reject:拒绝状态, 调用reject(),回调catch()中的函数

4.promise的链式调用

使用promise的链式调用可以层次是十分明的,相比于多层嵌套的Ajax易于阅读和管理。一个promise对象对应了一个异步操作。流程如下:

  1. 第一个new出来的Promise执行传入构造函数的回调函数
  2. 当遇到第一个resolve()时,执行第一个then中的回调函数
  3. 第一个then中的回调函数new了第二个Promise,并返回
  4. 第二个Promise也执行传入构造函数的回调函数
  5. 遇到第二个resolve(),执行第二个then中的回调函数
  6. 第二个then中的回调函数new出了第三个Promise对象
  7. 。。。。。。以此类推
new Promise((resolve,reject) =>{
	setTimeout(()=>{
		resolve('第一层')
	},1000)
}).then( data =>{
	console.log(data);   //-->第一层嵌套
    return new Promise((resolve,reject) =>{
      	resolve('第二层')
    })
}).then( data =>{
    console.log(data);   //-->第二层嵌套
    return new Promise((resolve,reject) =>{
      	resolve('第三层')
    })
})then( data =>{
    console.log(data);   //-->第三层嵌套
});

简写

/*
new Promise((resolve,reject) =>{
      	resolve(data)
    })
    如果下一层的也是只是调用resolve(),那么
    这种方式的调用可以简写成Promise.resolve(data)
*/
Promise.resolve(data)

5.Promise.all

Promise.all可以发起多个异步,并当这些异步都resolve或reject进行相应的回调。

Promise.all接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用 .then 方法。

Promise.all([
	new promise((resolve,reject)=>{
        //发起ajax请求
		$.ajax({
			url:'url1',
			success:function(data){
                //请求成功回调resolve(data)
				resolve(data)
			}
		})
	}),
    new promise((resolve,reject)=>{
        //发起ajax请求
		$.ajax({
			url:'url2',
			success:function(data){
                //请求成功回调resolve(data)
				resolve(data)
			}
		})
	})
]).then(results =>{
    //这里会等待上面的ajax都调用了resolve(data)才会执行这里
    //results是一个数组,里面包含了多个异步返回结果。
    //results[0],results[1]分别对应第一个promise和第二个promise返回的结果
    console.log(results);
})

6.Promise案例

console.log("1");
new Promise((resolve,reject)=>{
	setTimeout(() => {
		console.log("2");
    	resolve()
	})
}).then(data=>{
    console.log("3");
})
console.log("4");

//结果
/*
* 1
* 4
* 2
* 3
*/


console.log("1");
new Promise((resolve,reject)=>{
    console.log("2");
    resolve()
}).then(data=>{
    console.log("3");
})
console.log("4");
//结果
/*
* 1
* 2
* 4
* 3
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值