JS 异步新标准 -- Promise

JavaScript 的异步事件背景:

事件处理

	// 当元素被点击时,会触发对应事件处理函数
	<div onclick="handleClick">

	<script>
		function handleClick() {
			console.info('handle click.')
		}
	</script>

回调事件

	// 当读取文件完成后,会调用相应回调事件
	fs.readFile('path', (err, content) => {
		if (err) {
			throw err
		}
		console.info('content: ', content)
	})

优缺点

  • 事件处理函数
    • 只适用于响应用户交互和完成类似的低频功能,对于更复杂的需求来说不是很灵活
  • 回调函数
    • 嵌套地狱:
    	fs.readFile('path', (err, content) => {
    		if (err) {
    			throw err
    		}
    		fs.writeFile('filename', (err, result) => {
    			if (err) {
    				throw err
    			}
    
    			fs.openFile('path', (err, result) => {
    				if (err) {
    					throw err
    				}
    				console.info('open file success!')
    			})
    		})
    	})
    

Promise

定义:

Promise 是异步操作结果的占位符,承诺在未来某个时刻 完成

  • 3 种状态
    1. pending // 进行中
    2. fulfilled  // 成功
    3. rejected // 失败

一旦异步操作结束,Promise 即变为 settle 状态

  • 创建未完成的 Promise:
	let promise = new Promise(function (resolve, reject) {
		resolve()
		reject()
	})

	promise
		.then(() => console.info('resolved'))
		.catch(() => console.info('rejected'))

每次调用 thencatch 都会创建一个新任务,当 Promise 被解决时执行

	console.info('script start')

	const promise = new Promise(resolve => {
		console.info('Promise executed')
		resolve()
	})

	promise.then(() => console.info('resolved'))

	console.info('script end')

	// script start
	// Promise executed
	// script end
	// resolved
  • 具体执行机制是啥样呢

    1. new Promise(executor) 时,Promise 构造器中的执行器 executor 会立即执行;
    2. 在执行器中,无论调用 resolve() 还是 reject(),都会触发一个异步操作;
    3. 传入 then()catch() 的函数会被添加到任务队列中异步执行
  • 创建已完成的 Promise

    • Promise.resolve()
    	Promise.resolve(42).then(result => console.info(result)) // 42
    
    • Promise.reject()
    	Promise.reject('error').catch(err => console.error(err)) // 'error'
    
  • 非 Promise 的 Thenable 对象

Promise.resolve()Promise.reject()方法都可接受非 Promise 的 Thenable 对象作为参数,
这些方法会创建一个新的 Promise 并在 then() 函数中被调用。

	const thenable = {
		then: (resolve, reject) => resolve(42)
	}

	const promise = Promise.resolve(thenable)

	promise.then(result => console.info(result)) // 42
  • Promise 返回的也是 Promise 对象,因此可链式调用
	const promise = new Promise(resolve => setTimeout(resolve, 1000))

	promise
		.then(() => console.info('first promise'))
		.then(() => console.info('second promise'))
		.then(() => { throw Error('error') })
		.catch(err => console.error(err))
  • 任务队列、事件循环、宏任务、微任务

  • 错误捕获机制

    • 如果执行器内部抛出了错,则 Promise 的错误处理程序会被调用:
    	const promise = new Promise(() => { throw Error('error') })
    
    	promise.catch(err => console.error(err.message)) // 'error'
    
    	// 每个执行器中都隐含一个 try-catch 块,上例等价于:
    	let promise = new Promise((resolve, reject) => {
    		try {
    			throw Error('error')
    		} catch (err) {
    			reject(err)
    		}
    	})
    
    	promise.catch(err => console.error(err.message)) // 'error'
    
    • 全局的 Promise 拒绝处理:
      • Node.js 环境的拒绝处理:
        1. unhandledRejection
        2. rejectionHandled
      • 浏览器环境的拒绝处理
        1. unhandlerejection
        2. rejectionhandled
  • 响应多个 Promise:

    • Promise.all()
    	const promise1 = new Promise(resolve => setTimeout(() => resolve(42), 1000))
    	const promise2 = new Promise(resolve => setTimeout(() => resolve(43), 2000))
    
    	Promise.all([promise1, promise2]).then(results => console.info(results))
    	// 2s 后输出 [42, 43]
    
    
    • Promise.race()
    	const promise1 = new Promise(resolve => setTimeout(() => resolve(42), 1000))
    	const promise2 = new Promise(resolve => setTimeout(() => resolve(43), 2000))
    
    	Promise.race([promise1, promise2]).then(result => console.info(result))
    	// 1s 后输出 42
    
    
  • 生成器 + Promise

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值