原生JS记录1-promise

promise的学习使用

产生背景:

JS 作为单线程事件循环模型,异步编程可以缩短计算量较大的操作时间,并且可以避开某步操作阻塞线程执行。
早期的异步编程模式是通过定义回调函数来表明异步操作完成。串联多个异步操作需要深度嵌套的回调函数来解决。

一、认识

概念:ES6异步编程解决方案

作用:常用于封装ajax异步请求

底层:创建了Promise构造函数,并且给该构造函数绑定了then、catch、finally等原型方法,和reject、resolve、all、race等静态方法。

二、promise对象三种状态

Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态.

语法:

 var p = new Promise(function(resolve,reject){})
 resolve 代表 决定(成功); reject 代表 失败
const p = new Promise((resolve, reject) => {
	// 发送异步请求
	// 默认触发的  所以是进行中状态
})

追问:为什么状态不可逆

回答:底层Promise构造函数中会判断当前是否是pending进行中状态,不是就会终止代码执行 所以不可逆.

追问:状态之间怎么转换?

回答:通过promise的then机制,来实现状态切换

三、使用

    const p = new Promise(function(resolve,reject){
        setTimeout(function(){
           // resolve('我是成功的')
           reject('这是失败的');
        },2000)
    };
    p.then(function(data){
			console.log('resolved成功回调');
		}).catch(function(reason, data){
		    console.log('catch到rejected失败回调');
	});	

常用模式:

1. promise对象作为函数返回值

let promiseFn =()=>{
	 console.log('点击方法被调用')
	 let p = new Promise(function(resolve, reject){
		//做一些异步操作
		setTimeout(function(){
				console.log('执行完成Promise');
				resolve('成功的时候调用');
			}, 2000);
		});
        return p
	}

promiseFn().then(function(data){
     console.log(11111)
}).catch(function(data){
     console.log(2222)
})

2. 结合ajax使用

串联请求场景下,当第一次发送的网络请求得到的数据,为第二次请求所必须的数据,使用promise

Promise 链式调用

+ 当你在第一个 then 内部返回一个新的 Promise 对象的时候可以把新的 Promise 的 then 连续书写   

      pAjax({ url: 'http://localhost:8888/test/first' })
           .then(res => {
             console.log(res)
             // 这里是第一个请求完成后会执行的代码
     
             // 调用 pAjax, 创建的第二个 承若(Promise)
             // 在第一个 then 里面把新的 Promise return 了
             return pAjax({ url: 'http://localhost:8888/test/second', dataType: 'json' })
           })
           .then(res2 => {
             console.log(res2)
     
             // 这里是第二个请求完成后会执行的代码
     
             // 调用 pAjax, 创建第三个 承诺(Promise)
             // 在第二个 then 里面被写的 Promise return 了
             return pAjax({ url: 'http://localhost:8888/test/third', data: 'name=Jack&age=20', dataType: 'json' })
           })
           .then(res3 => console.log(res3))

其他技巧:

1. 期约合并

方法一:promise.all()
概念:所有的异步请求完成才执行

案例:一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。

let wake = (time) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time / 1000}秒后醒来`)
    }, time)
  })
}

let p1 = wake(3000);
let p2 = wake(2000);

// 只有两次调用promise都执行完毕,才会执行all
Promise.all([p1, p2]).then((result) => {
  console.log(result)       // [ '3秒后醒来', '2秒后醒来' ]
}).catch((error) => {
  console.log(error)
})

方法二:promise.race()

概念:Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  },1000)
})

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('failed')
  }, 500)
})

Promise.race([p1, p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)  // 打开的是 'failed'
})

2. 增强语法:async 和 await 关键字

async function fn() {
  console.log('start')
  // 等着第一个请求
  const r1 = await pAjax({ url: 'http://localhost:8888/test/first' })
  console.log(r1)

  // 如果上面的 请求没有结束, 那么这里的代码不会执行
  // 这里的代码执行了, 一定是因为 await 等到了上面的请求结束
  const r2 = await pAjax({ url: 'http://localhost:8888/test/second', dataType: 'json' })
  console.log(r2)

  const r3 = await pAjax({ url: 'http://localhost:8888/test/third', data: 'name=Jack&age=20', dataType: 'json' })
  console.log(r3)

  console.log('end')
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值