JavaScript入门 Promise/本地存储Storage Day27

Promise[ES6新增一个对象]


语法

resolve 函数:处理异步任务成功的结果  -> resolve('成功')

reject 函数:处理异步任务失败的结果  -> resolve('失败')

let promise = new Promise(function(resolve,reject)){
    //resolve 函数
    //reject 函数
    //异步任务封装
    setTimeout(function(){
        if(true){
          resolve('成功')  
        }else{
            reject('成功')
        }
    },1000)
})
promise.then(function(result){  //与回调函数不同 结果用then来返回
    result=>成功
})
promise.catch(function(error){
    error=>失败
})

作用

同回调函数一样对异步任务进行封装,但能更好的更优雅的处理异步任务结果

使用

let promise = new Promise(function(resolve,reject)){
    //resolve 函数
    //reject 函数
    //异步任务封装
    setTimeout(function(){
        if(true){
          resolve('成功')  
        }else{
            reject('成功')
        }
    },1000)
})
promise.then(function(result){
    result=>成功
})
promise.catch(function(error){
    error=>失败
})

promise AJAX封装

function myPromise(options) {
	return new Promise((resolve, reject) => {
		ajax({
			method: options.method,
			url: options.url,
			data: options.data,
			success: function (result) {
				resolve(result)
			},
			fail:function(error){
				reject(error)
			}
		})
	})
}

promise链式调用

比 回调函数 更好的更优雅的方法处理异步结果

有多个请求,后面请求需要用到前面请求的结果,若使用回调函数,会出现回调嵌套(回调地狱问题)

请求:A -> B(a) -> C(b)

参数: a b

            // 链式写法 简化改良版
             promiseA.then(a=>{
                 let promiseB = new Promise((resolve,reject)=>{
                    //封装B异步操作 a
                 })
                 return promiseB
             }).then(b=>{  //用then处理结果
                  let promiseC = new Promise((resolve,reject)=>{
                        //封装C异步操作 b
                  })
                  return promiseC
             }).then(c=>{
                 console.log(c)
             })
    //未简化版
        let promiseA = new Promise((resolve,reject)=>{
                 //封装A异步操作
             })          
             let promiseC = new Promise((resolve,reject)=>{
                 //封装C异步操作
             })
             promiseA.then(a=>{
                 成功结果
                 let promiseB = new Promise((resolve,reject)=>{
                    //封装B异步操作 a
                 })
                 promiseB.then(b=>{
                     let promiseC = new Promise((resolve,reject)=>{
                        //封装C异步操作 b
                    })
                    promiseC.then(c=>{
                    })
                 })
             })

 链式调用事例

        <script src="./myajax.js"></script>
		<script>
			/*
          封装一个函数获取promsie对象, promise对象封装处理网络请求异步任务
          options = {
              method:'get',
              url:''
              data:{}
          }
        */
			myPromise({
				method: 'get',
				url: 'http://10.7.162.150:8089/api/shop/list',
			}).then(result => {
					let list = result.resultInfo.list //商品列表
					return myPromise({
						method: 'get',
						url: 'http://10.7.162.150:8089/api/shop/find',
						data: {
							id: list[0].id,   //商品详情
						},
					})
				}).then(resultB => {
					console.log(resultB)
				})
		</script>

如何使用promise

            写项目
           调用接口获取后端数据
           1. 原生ajax
               let xhr = new XMLHttpRequest()
               xhr.open()
               xhr.send()
               xhr.onreadystatechange=function(){
               }
            2. 封装ajax回调函数
               引入myajax.js
               ajax({
                   method:'get',
                   url:'',
                   data:{},
                   success:function(res){},
                   fail:function(error){}
               })
            3. 封装promise写法
                引入myajax.js
                myPromise({
                    method:'get',
                    url:'',
                    data:{}
                }).then(res=>{
                    成功
                }).catch(error=>{
                    失败
                })
     -->

 

product

商品列表:

    <div class="container">
        <!-- 动态渲染 -->
    </div>
    <script src="./js/myajax.js"></script>
<script>
/**
 * 获取商品列表数据
 */
function getProductList() {
	// ajax({
	// 	method: 'get',
	// 	url: 'http://10.7.162.150:8089/api/shop/list',
	// 	success: function (res) {
	// 		showProductList(res.resultInfo.list)
	// 	},
	// })
	myPromise({
		method:'get',
		url:'http://10.7.162.150:8089/api/shop/list',
	}).then(res=>{
		showProductList(res.resultInfo.list)
	})
}
/**
 * 动态渲染商品列表
 */
function showProductList(productList) {
	let list = productList.map(item => {
		return `<div class="product-item" onclick="onDetail(${item.id})">
                    <img src="${item.picture}" alt="pic1">
                    <p>${item.product}</p>
                    <p>¥${item.price}  ${item.putaway}人已买</p>
                </div>`
	})
	const rootEle = document.querySelector('.container')
	rootEle.innerHTML = list.join('')
}
/**
 * 跳转详情页
 * @param {*} id 
 */
function onDetail(id) {
	// 跳转详情页
	location.href = './detail.html?id=' + id
}
getProductList()
</script>

商品详情 放大镜: 

        <a href="./index.html">返回首页</a>
		<div class="glass-wrapper">
			<!-- 动态渲染 -->
		</div>
		<script src="./js/myajax.js"></script>
		<script src="./js/glass.js"></script>
<script>
/**
 *  获取商品id
 * @returns
 */
function getProductId() {
	let str = location.search // ?id=2
	let id = str.split('=')[1]
	return id
}
/**
 * 获取商品详情
 */
function getProductDetail() {
	let id = getProductId()
	// ajax({
	// 	method: 'get',
	// 	url: 'http://10.7.162.150:8089/api/shop/find',
	// 	data: {
	// 		id,
	// 	},
	// 	success: function (res) {
	// 		showProductDetail(res.resultInfo)
	// 	},
	// })
	myPromise({
		method:'get',
		url:'http://10.7.162.150:8089/api/shop/find',
		data:{id}
	}).then(res=>{
		console.log(res)
		showProductDetail(res.resultInfo)
	})
}
/**
 * 动态渲染详情
 */
function showProductDetail(product) {
	let str = `<div class="container" id="glass1">
                <div class="left-wraper">
                    <div class="m-left">
                        <img src="${product.picture}" alt="show1" />
                        <!-- 遮罩层 -->
                        <div class="mask"></div>
                    </div>
                    <ul>
                        <li class="active"><img src="${product.list[0]}" alt="small1" /></li>
                        <li><img src="${product.list[1]}" alt="small2" /></li>
                        <li><img src="${product.list[2]}" alt="small3" /></li>
                        <li><img src="${product.list[3]}" alt="small4" /></li>
                    </ul>
                </div>
                <!-- 放大镜 -->
                <div class="right-wraper">
                    <img src="${product.picture}" alt="big1" />
                </div>
           </div>`
	const detailWraper = document.querySelector('.glass-wrapper')
	detailWraper.innerHTML = str
	// 数据动态渲染完成后,再操作放大镜节点
	let glass = new Glass('#glass1')
	glass.setScale()
	glass.onGlass()
	glass.onTab(product)
}
getProductDetail()
</script>
/**
 * 放大镜类
 */
 class Glass {
	constructor(id) {
		this.rootEle = document.querySelector(id)
		this.mask = this.rootEle.querySelector('.mask') //mask遮罩层
		this.showBox = this.rootEle.querySelector('.m-left') //showbox显示盒子
		this.glassBox = this.rootEle.querySelector('.right-wraper') // 放大镜glassBox
		this.bgPic = this.rootEle.querySelector('.right-wraper>img') //背景图bgpic
        this.ulLis = this.rootEle.querySelectorAll('.left-wraper ul>li')
        this.showBoxPic = this.showBox.querySelector('img')
	}
	/**
	 * 计算放大镜图片的比例
	 *    目的: 遮罩层区域遮罩区域大小 与 放大镜放大区域大小相同
	 *      遮罩层mask           放大镜
	 *     -------------- =  -----------------
	 *      显示盒子showBox      背景图 ?
	 *     背景图 = 放大镜* showBox / mask
	 */
	setScale() {
		// 遮罩层mask
		let maskW = parseInt(window.getComputedStyle(this.mask).width)
		let maskH = parseInt(window.getComputedStyle(this.mask).height)
		// 显示盒子showBox
		let showBoxW = parseInt(window.getComputedStyle(this.showBox).width)
		let showBoxH = parseInt(window.getComputedStyle(this.showBox).height)
		// 放大镜glassBox
		let glassBoxW = parseInt(window.getComputedStyle(this.glassBox).width)
		let glassBoxH = parseInt(window.getComputedStyle(this.glassBox).height)
		// 背景图
		let bgPicW = (glassBoxW * showBoxW) / maskW
		let bgPicH = (glassBoxH * showBoxH) / maskH
		this.bgPic.style.width = bgPicW + 'px'
		this.bgPic.style.height = bgPicH + 'px'
	}
	/**
	 * 遮罩层移光标移动
	 *    offsetX offsetY  相对自身
	 *    clientX clientY  浏览器
	 *    pageX   pageY    页面
	 *
	 *    window.getComputedStyle(ele).width
	 *    offsetWidth
	 *    clientWidth
	 */
	onGlass() {
		let _this = this
        // 移入显示
        this.showBox.addEventListener('mouseover',()=>{
            this.mask.style.display = 'block'
            this.glassBox.style.display = 'block'
        })
        // 移出隐藏
        this.showBox.addEventListener('mouseout',()=>{
            this.mask.style.display = 'none'
            this.glassBox.style.display = 'none'
        })
		//showBox鼠标移动事件
		this.showBox.addEventListener('mousemove', function (e) {
			e = e || window.event
			let x = e.offsetX - _this.mask.clientWidth / 2
			let y = e.offsetY - _this.mask.clientHeight / 2

			// 边界检查
			if (x < 0) {
				x = 0
			}
			if (x > _this.showBox.clientWidth - _this.mask.clientWidth) {
				x = _this.showBox.clientWidth - _this.mask.clientWidth
			}
			if (y < 0) {
				y = 0
			}
			if (y > _this.showBox.clientHeight - _this.mask.clientHeight) {
				y = _this.showBox.clientHeight - _this.mask.clientHeight
			}
			// 移动遮罩层
			_this.mask.style.left = x + 'px'
			_this.mask.style.top = y + 'px'

			// 移动背景图片
			/*
               遮罩层       遮罩层移动距离
               ------ =   -----------------
               放大镜        背景图移动距离?
                背景图移动距离= 遮罩层移动距离*放大镜/遮罩层
            */
			// 遮罩层mask
			let maskW = parseInt(window.getComputedStyle(_this.mask).width)
			let maskH = parseInt(window.getComputedStyle(_this.mask).height)
			// 放大镜glassBox
			let glassBoxW = parseInt(window.getComputedStyle(_this.glassBox).width)
			let glassBoxH = parseInt(window.getComputedStyle(_this.glassBox).height)
            let moveX = x * glassBoxW / maskW
            let moveY = y * glassBoxH / maskH
			_this.bgPic.style.left = -moveX + 'px'
			_this.bgPic.style.top = -moveY + 'px'
		})
	}
    /**
     * 切换图片
     */
    onTab(product){
        let _this = this
        for(let i = 0; i < this.ulLis.length; i++){
            this.ulLis[i].addEventListener('mouseover',function(){
                // 清除所有选中效果
                _this.onClear()
                // 当前选设置选中效果
                this.className = 'active'
                // 显示盒子图片
                _this.showBoxPic.setAttribute('src',`${product.list[i]}`)
                // 背景图片切换
                _this.bgPic.setAttribute('src',`${product.list[i]}`)
            })
        }
    }
    onClear(){
        for(let i = 0; i < this.ulLis.length; i++){
            this.ulLis[i].className = ''
        }
    }
}

 封装ajax promise:

function myPromise(options) {
	return new Promise((resolve, reject) => {
		ajax({
			method: options.method,
			url: options.url,
			data: options.data,
			success: function (result) {
				resolve(result)
			},
			fail: function (error) {
				reject(error)
			},
		})
	})
}
function ajax(options) {
	// 1. 创建XMLHttpRequest
	let xhr = new XMLHttpRequest()
	let param = formateParam(options.data) // name=jack&age=18
	let method = options.method.toUpperCase()
	// 2. 建立连接
	if (method == 'GET') {
		xhr.open(options.method, options.url + '?' + param)
		// 3. 发送请求
		xhr.send()
	} else if (method == 'POST') {
		xhr.open(options.method, options.url)
		xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
		xhr.send(param)
	}
	// 4. 接收响应数据
	xhr.onreadystatechange = function () {
		// 4.1 是否响应完成
		if (xhr.readyState === 4) {
			// 4.2 是否成功响应
			if (xhr.status === 200) {
				let data = xhr.responseText // 响应内容
				data = JSON.parse(data)
				options.success(data)
			} else {
				alert('网络出错 ' + xhr.status)
			}
		}
	}
}
/**
 * 格式化参数
 *  {name:'jack',age:18}  =>  name=jack&age=18
 *   遍历对象,属性转换成名称=值形式,存储到数组, 再将数组元素用&符号拼接join('&)
 *    ['name=jack','age=18']  ->
 */
function formateParam(obj) {
	let arr = []
	for (const key in obj) {
		let item = `${key}=${obj[key]}` // name=jack   age=18
		arr.push(item) // ['name=jack','age=18;]
	}
	return arr.join('&') // name=jack&age=18
}

promise三种状态

pending(进行中)、fulfilled(已成功)和rejected(已失败) 

  • 对象的状态不受外界影响。Promise对象代表一个异步操作,只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
  • 一旦状态改变,就不会再变从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。

 Promise类对象方法

  • 类对象 Person
  • 实例对象 new Person('jack',18)
  • 原型对象Person.prototype
  •  new Promise().then().catch()  [实例对象的方法]
                //已引入封装promise.js
                let promise1 = myPromise({
    				method: 'get',
    				url: 'http://10.7.162.150:8089/api/shop/list',
    			})
    			promise1.then(res=>{
    			     console.log('商品列表',res);
    			})
    			// 获取bannber轮播列表
    			let promise2 = myPromise({
    				method: 'get',
    				url: 'http://10.7.162.150:8089/api/shop/banner',
    			})
    			promise2.then(res=>{
    			    console.log('bannber列表 ',res);
    			})

 Promise类对象方法不用定义实例对象(new Promise())

1.Promise.all([promise1,promise2...])

=>Promise对象 包含数组中所有promise对象执行的结果

let promise1 = myPromise({
				method: 'get',
				url: 'http://10.7.162.150:8089/api/shop/list',
			})
let promise2 = myPromise({
				method: 'get',
				url: 'http://10.7.162.150:8089/api/shop/banner',
			})
 Promise.all([promise1, promise2]).then(res => console.log('res >> ', res))

2.Promise.race([promise1,promise2...]).then(res=>{})

=>竞争

=>最先执行完的异步promise结果

Promise.race([promise1, promise2]).then(res => console.log(res))

3.Promise.reject('失败').catch(error=>{})

Promise.resolve('成功').then(res=>console.log(res))

4.Promise.resolve('成功').then(res=>{})

Promise.reject('失败').then(null,error=>console.log(error))
Promise.reject('失败').catch(error=>console.log(error))
         // 满足条件返回promise对象
            function test(){
                if(true){
                    // new Promise(()=>{ })
                   return Promise.resolve('成功')
                }else{
                    Promise.reject('失败')
                }
            }

本地存储 Storage


本地存储 Storage

        电脑硬盘 存储化存储数据

        电脑内存 临时数据 -电脑关机或者程序终止数据消失

locationStorage对象

        locationStorage.setItem(key1,value1) //存储一条数据到locationStorage

        locationStorage.setItem(key2,value2) //存储一条数据到locationStorage

        let value1 = locationStorage.getItem(key1)  //获取locationStorage数据

            function test1() {
			localStorage.setItem('num', 100) // 向localStorage存key为num值为100的一条数据
		localStorage.setItem('state', true) // 向localStorage存key为state值为true的一条数据
				let num1 = localStorage.getItem('num')
				let state = localStorage.getItem('state')
				console.log('获取num值是 ', typeof num1)
				console.log('state类型 ', typeof state, ' state :', state)
				if (state) {
					console.log('成立')
				} else {
					console.log('不成立')
				}
				// 取对象
			}
			test1()

        locationStorage.removeItem(key) //移出key对应数据

        clear()  //清空所有数据

                function test3() {
				let newProudct1 = {
					id: 1001,
					name: 'javascript高级编程',
					url: 'https://img2.baidu.com/it/u=544283419,3814727158&fm=253&fmt=auto&app=120&f=JPEG?w=477&h=307',
					price: 100,
					num: 0,
				}
				// 商品存储到数组,将数组持久化存储到localStorage,一条一条存储
				let list = localStorage.getItem('list') || '[]' // 如果localStorage没有存储过商品返回空数组
				list = JSON.parse(list)
				list.push(newProudct1)
				localStorage.setItem('list', JSON.stringify(list))
				// 添加第二条商品
				let newProudct2 = {
					id: 1002,
					name: 'vue高级编程',
					url: 'https://img0.baidu.com/it/u=213764802,1949531026&fm=253&fmt=auto&app=138&f=JPEG?w=417&h=236',
					price: 100,
					num: 0,
				}
				let list1 = localStorage.getItem('list') || '[]'
				list1 = JSON.parse(list1)
				list1.push(newProudct2)
				localStorage.setItem('list', JSON.stringify(list1))
			}
			test3()

        key 类型 字符串类型

        value 字符串

let obj = {name:'jack',age:18}
JSON.stringify(obj)
true -> 'true'
100 -> '100'

浏览器 application选项查看localStorage持久化存储的数据

function test3() {
				let newProudct1 = {
					id: 1001,
					name: 'javascript高级编程',
					url: 'https://img2.baidu.com/it/u=544283419,3814727158&fm=253&fmt=auto&app=120&f=JPEG?w=477&h=307',
					price: 100,
					num: 0,
				}
				// 商品存储到数组,将数组持久化存储到localStorage,一条一条存储
				let list = localStorage.getItem('list') || '[]' // 如果localStorage没有存储过商品返回空数组
				list = JSON.parse(list)
				list.push(newProudct1)
				localStorage.setItem('list', JSON.stringify(list))
				// 添加第二条商品
				let newProudct2 = {
					id: 1002,
					name: 'vue高级编程',
					url: 'https://img0.baidu.com/it/u=213764802,1949531026&fm=253&fmt=auto&app=138&f=JPEG?w=417&h=236',
					price: 100,
					num: 0,
				}
				let list1 = localStorage.getItem('list') || '[]'
				list1 = JSON.parse(list1)
				list1.push(newProudct2)
				localStorage.setItem('list', JSON.stringify(list1))
			}
			test3()

购物车3.0 localStorage中持久化存储

<div class="containter">
			<table>
				<!-- 动态渲染 -->
			</table>
		</div>
		<!-- 商品表单 -->
		<div class="prowraper">
			<form>
				<input type="text" name="name" placeholder="请输入商品名"><br/>
				<input type="text" name="price" placeholder="请输入商品价格"> <br/>
				<input type="text" name="num" placeholder="请输入商品数量"> <br/>
				<input type="text" name="url" placeholder="请输入商品图片地址"> <br/>
				<input type="submit" id="confirm" value="添加商品">
			</form>
		</div>
		<script src="./js/cart.js"></script>
/**
 *  1. 显示商品列表
 *      => 动态渲染localStorage中持久化存储的商品列表数据
 */
function showProductList(){
    let listStr = localStorage.getItem('list') || '[]'
    list = JSON.parse(listStr) // 商品列表
    let str = `<tr>
                <th>序列号</th>
                <th>商品图片</th>
                <th>商品信息</th>
                <th>单价</th>
                <th>数量</th>
                <th width="100px">总价</th>
                <th>操作</th>
            </tr>`
    let arr = list.map(item=>{
        return `<tr>
             <td>${item.id}</td>
             <td><img src="${item.url}" alt="pic1"/></td>
             <td>${item.name}</td>
             <td>${item.price}</td>
             <td><input type="button" value="-" name="minus"  ${item.num == 0 ? 'disabled' : ''}    data-id="${
                item.number
            }"/><input type="text" value="${item.num}" name="amount"/><input
                                type="button"
                                value="+"
                                name="plus"
                                data-id="${item.number}"
                            /></td>
             <td>${item.num * item.price}</td>
             <td>移入收藏<br /><a href="javascript:void(0)" class="del" data-id="${item.id}">删除</a></td>
        </tr>`
    })
    const tableEle = document.querySelector('table')
    tableEle.innerHTML = str + arr.join('')
}
/**
 * 绑定添加商品事件
 */
 function bindAddProduct() {
	const formEle = document.querySelector('form')
	const nameInput = document.querySelector('input[name="name"]')
	const priceInput = document.querySelector('input[name="price"]')
	const numInput = document.querySelector('input[name="num"]')
	const urlInput = document.querySelector('input[name="url"]')
	formEle.addEventListener('submit', function (e) {
		e = e || window.event
		e.preventDefault() // 阻止默认行为
		let name = nameInput.value // 商品名称
		let price = priceInput.value // 商品价格
		let num = numInput.value // 商品数量
		let url = urlInput.value // 商品地址
		addProduct(name, price, num, url)
		// 清空表单数据
		nameInput.value = ''
		priceInput.value = ''
		numInput.value = ''
		urlInput.value = ''
	})
}
function addProduct(name,price,num,url){
    let id = getRandom(1000, 10000) // 随机生成4位商品序号

    // 持久化存储商品到localStorage
    let listStr = localStorage.getItem('list') || '[]'
    let list = JSON.parse(listStr)
    list.push({
        id,
        name,
        price,
        num,
        url
    })
    //持久化存储到localStorage
    localStorage.setItem('list',JSON.stringify(list))
    showProductList()
}
/*
 * 返回m到n之间的随机数
 */
function getRandom(x, y) {
	var n = Math.max(x, y)
	var m = Math.min(x, y)
	return Math.floor(Math.random() * (n - m) + m)
}
showProductList()
bindAddProduct()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值