js高级--异步函数,回调函数与Promise对象

Promise对象

在说promise之前先谈谈异步,前面学习了ajax就是一个异步方法,在ES6之前为了获取异步代码里面的数据用的是回调函数:

function getTi(callback){
				setTimeout(function(){
					callback('喝茶')
				},2000)
			}
			getTi(function(data){
				console.log(data);
			})

这里再说下,js是单线程,所以在代码执行过程中,遇到异步代码会先放到队列里面,先执行同步代码,完了回来再执行异步代码(轮循),异步代码谁花费时间短谁会先进入执行待序列,但是有时候我们的一些需求对异步代码是有顺序要求的(与其本身时间无关),代码本身又没有办法自己控制,所以采用下列这种方法来做:

function getTi(callback){
				setTimeout(function(){
					callback('喝茶')
				},2000)
			}
			function getHuo(back){
				setTimeout(function(){
					back('吃火锅')
				},5000)
			}
			getHuo(function(data){
				console.log(data);
				getTi(function(data){
					console.log(data);
				})
			})

这只是两个时间,如果再多几个事情就会造成多重的嵌套,也就是常说的回调地狱,所以ES6新增了promise来解决这个问题

1、promise概念
  • Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
  • 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
  • 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
2、promise特点

有且只有这两种,而且一个peomise对象只能改变一次,无论变为成功还是失败,都会有一个结果数据,成功的结果数据一般为value,失败的结果数据一般被称为reason

它只有两种状态(PromiseState)可以转化,即

  • **操作成功:**pending -> fulfilled/resolved
  • **操作失败:**pending -> rejected

实例对象的值:PromiseResult。该对象保存的结果为异步任务成功和失败的结果

  • 成功的结果 resolve
  • 失败的结果 rejected

代码展示:

 const p = new Promise((resolve,reject)=>{
     setTimeout(()=>{
         let n = Math.floor(Math.random()*100);
         if (n<=30) {
             resolve(n);
         } else {
             reject(n);
         }
     })
 })
 p.then(value=>{
     console.log(value);
 })
console.log(p);

promise有三个状态:
1、pending[待定]初始状态
2、fulfilled[实现]操作成功
3、rejected[被否决]操作失败

resolve作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
3、promise实现原理

ES6 规定,Promise 对象是一个构造函数,用来生成 Promise 实例。通过在函数内部 return 一个 Promise 对象的实例,这样就可以使用 Promise 的属性和方法进行下一步操作了。

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署

new Promise(
  function (resolve, reject) {
    // 一段耗时的异步操作
    resolve('成功') // 数据处理完成
    // reject('失败') // 数据处理出错
  }
).then(
  (res) => {console.log(res)},  // 成功
  (err) => {console.log(err)} // 失败
)

promise的方法:then()方法就是把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数.

Promise的优势就在于这个链式调用。我们可以在 then 方法中继续写 Promise 对象并返回,然后继续调用 then 来进行回调操作。

问题一:函数内部的异步函数

var a=(function(){
  setTimeOut(()=>'data',1000)
})

怎样才能取得到函数内部的data

1、promise构造函数的参数是个函数
2、该函数的参数有两个:resolve,reject
  resolve:异步操作成功,要调用的函数。是then函数的第一个参数
  reject表示操作失败,要调用的时候是then函数的第二个参数
var p =new Promise(function(resolve,reject){
    异步操作的代码
    如果异步操作成功,调用resolve;如果失败,调用reject;
});

方法:then()       可以通过then拿到异步数据
var  p = new Promise(function(resolve){       resolve:可以将异步的数据传递出来
    resolve('helloworld')
})

p.then(function(data){
    consloe.log(data);//hellowrld
})  拿到异步的数据
     function getTea() {
          return new Promise(function(resolve){
              setTimeout(function () {
                  resolve('奶茶');
              }, 1000)
          })
     }

        function getHotpot(){
            return new Promise(function(resolve){
                resolve('火锅')
            },2000)
        }


--------------------------如何先吃火锅再喝奶茶呢?---------------------------------------
    
     getTea().then(function(data){
         console.log(data)
         return getHotpot();
     }).then(function(data){
          console.log(data)
        })


4、promise的api方法

4.1、.then(callback)

Promise对象含有then方法,then()调用后返回一个Promise对象,意味着实例化后的Promise对象可以进行链式调用,而且这个then()方法可以接收两个函数,一个是处理成功后的函数,一个是处理错误结果的函数。

var promise1 = new Promise(function(resolve, reject) {
  // 2秒后置为接收状态
  setTimeout(function() {
    resolve('success');
  }, 2000);
});

promise1.then(function(data) {
  console.log(data); // success
}, function(err) {
  console.log(err); // 不执行
}).then(function(data) {
  // 上一步的then()方法没有返回值
  console.log('链式调用:' + data); // 链式调用:undefined 
}).then(function(data) {
  // ....
});

4.2、.catch(callback)

catch()方法和then()方法一样,都会返回一个新的Promise对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略then()方法的第二个参数,把错误处理控制权转交给其后面的catch()函数

const p = new Promise((resolve, reject) => {
            //  修改p的状态
    reject('失败')
})
console.log(p);
p.catch(data => {
    console.log(data);
})

4.3、.all()

Promise.all()

Promise包含n个promise的数组,说明:返回一个新的promise,只有promise都成功才成功,只要有一个失败了,就都失败

 const p1 = new Promise((resolve, reject) => {
     resolve('ok')
 })
 const p2 = new Promise((resolve, reject) => {
     resolve('okhaha')
 })
 const p3 = new Promise((resolve, reject) => {
     resolve('kobab')
 })
 const result = Promise.all([p1,p2,p3]);
console.log(result);


||  一真即真
&&  一假即假

4.4 .race()

Promise包含n个promise的数组,说明:返回一个promise,第一个完成的promise的结果状态就是最终的结果状态

 const p1 = new Promise((resolve, reject) => {
     resolve('ok')
 })
 const p2 = new Promise((resolve, reject) => {
     resolve('jj')
 })
 const p3 = new Promise((resolve, reject) => {
     resolve('ll')
 })
 const result = Promise.race([p1,p2,p3]);
console.log(result);
5、promise封装ajax
function promise(obj){
	return new Promise(function(reslove,reject){
	var xhr=new XMLHttpRequest();
	if(obj.type=='get'||obj.type=='GET'){
	xhr.open(obj.type,obj.url+'?'+setstr(obj.data),obj.async);
	xhr.send();
	}else if(obj.type=='post'||obj.type=='POST'){
	xhr.open(obj.type,obj.url,obj.async);
	xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xhr.send(setstr(obj.data));
							}
	xhr.onreadystatechange=function(){
		if(xhr.readyState==4){
			if(xhr.status==200){
				reslove(xhr.responseText);
			}else{
				reject('错误');
							}
								}
				}
						})
						}
						
				function setstr(data){//将对象转为字符串
						var arr=[];
						for(k in data){
							arr.push(k+'='+data[k]);
						}
						return arr.join('&');
					}

调用

promise({
					type:'get',
					url:'text08.php',
					async:true,
					data:{
						a:3,
						b:2,
					}
				}).then(function(data){
					console.log(data); return promise({
					type:'get',
					url:'text09.php',
					async:true,
					data:{
						a:3,
						b:2,
					}
				}).then(function(data){console.log(data)})
				})
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值