Promise学习笔记(知识点 + 手写Promise)
标签:
JavaScript
Promise标准了解一下
传送门️ Promises/A+规范
传送门️ 阮一峰前辈ECMAScript 6入门——Promise对象
Promise重点难点
Promise的状态不受外界影响,只由Promise内的异步操作结果决定。
Promise的状态一旦改变就不会再变。
pending fulfilled
pending rejected
Promise的构造函数是同步的,then()方法中的函数是异步的。
then()方法或者catch()方法的参数期望是函数,传入非函数则会发生值穿透
Promise属于microtask,同一次事件循环中,microtask永远在macrotask之前执行。
手写promise
实现基本状态(pending, fulfilled, rejected)
实现then方法
返回一个promise,实现链式调用
实现状态判断
实现resolve函数
接受一个Promise作为参数时的情况,实现链式Promise
执行回调函数时使用setTimeout,保证在注册then方法后触发
实现Promise.all,Promise.race方法
(function (window) { var Promise = function (fn) { var value = null; var callbacks = []; var state = 'pending'; // pending, fulfilled, rejected var promise = this; // 注册then事件,供resolve后调用 promise.then = function (onFulfilled, onRejected) { // 返回promise实现链式promise调用 return new Promise(function (resolve, reject) { handle({ onFulfilled: onFulfilled || null, onRejected: onRejected || null, resolve: resolve, reject: reject }) }) } promise.catch = function(onRejected) { return promise.then(undefined, onRejected) } function handle (callback) { // 状态变化前,事件推进队列里;状态一旦变化后不再变动,直接执行结果 if (state === 'pending') { callbacks.push(callback); } else { var cb = state === 'fulfilled' ? callback.onFulfilled : callback.onRejected // then方法没有传递任何参数的情况下,返回结果值 if (!cb) { cb = state === 'fulfilled' ? callback.resolve : callback.reject; cb(value) } else { try { var ret = cb(value); callback.resolve(ret); } catch (e) { callback.reject(e) } } } } function resolve(newValue) { // 状态一旦改变便不再改变 if (state !== 'pending') return // 假如resolve了一个promise的话(链式promise) if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { var then = newValue.then; if (typeof then === 'function') { // 调用第二个promise中的then,递归直到不是一个promise值为止 then.call(newValue, resolve, reject); return } } value = newValue; state = 'fulfilled'; execute() } function reject(reason) { // 状态一旦改变便不再改变 if (state !== 'pending') return state = 'rejected' value = reason execute() } function execute() { // 使用setTimeOut保证resolve一定在then事件注册后执行 setTimeout(() => { callbacks.forEach(function (callback) { handle(callback); }) }, 0); } fn(resolve, reject); } Promise.all = function (promises) { if (!Array.isArray(promises)) { throw new TypeError('请传入promise数组') } return new Promise(function (resolve, reject) { var result = []; var count = promises.length function reslover (index) { return function(value) { resloveAll(index, value) } } function rejecter (reason) { reject(reason) } function resloveAll (index, value) { result[index] = value // 等待全部promise执行完才执行resolve一个数组 if (--count === 0) { resolve(result) } } promises.forEach(function (promise, index) { promise.then(reslover(index), rejecter) }) }) } Promise.race = function (promises) { if (!Array.isArray(promises)) { throw new TypeError('请传入promise数组') } return new Promise(function (resolve, reject) { function reslover (value) { resolve(value) } function rejecter (reason) { reject(reason) } promises.forEach(function (promise, index) { promise.then(reslover, rejecter) }) }) } window.Promise = Promise})(window)/******************************************实例 */function test(i) { return new Promise(function (resolve) { setTimeout(() => { resolve(i); }, 1000); }) }function test2(i) { return new Promise(function (resolve, reject) { setTimeout(() => { if (i % 2) { resolve(i); } else { reject(i); } }, 2000); }) }// 链式Promisetest(1).then(test2).then(function (something) { console.log('case1: success!' + something); }).catch(function (something) { console.log('case1: failed!' + something); })// Promise.allPromise.all([test(2), test2(4)]).then(function (something) { console.log('case2: success!' + something); }).catch(function (something) { console.log('case2: failed!' + something) })// Promise.racePromise.race([test(3), test2(5)]).then(function (something) { console.log('case3: success!' + something); }).catch(function (something) { console.log('case3: failed!' + something) })// 多次改变状态,只有第一次生效function test3 () { return new Promise((resolve, reject) => { setTimeout(() => { resolve('success1') reject('error') resolve('success2') },0) }) } test3().then((res) => { console.log('then: ', res) })// 一旦改变状态后,多次调用then()方法也只会马上得到Promise返回的值,Promise构造函数不会多次执行function test4 () { return new Promise((resolve, reject) => { setTimeout(() => { resolve('success') }, 1000) }) } const start = Date.now() test4().then((res) => { console.log(res, Date.now() - start) }) test4().then((res) => { console.log(res, Date.now() - start) })
小礼物走一走,来简书
作者:Eason_Wong
链接:https://www.jianshu.com/p/b7eba0d43af9
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦