当前位置: 首页 > news >正文

商丘市住房和城乡建设局网站推广的几种方式

商丘市住房和城乡建设局网站,推广的几种方式,软件开发软件下载,wordpress 分页浅谈对Promise的理解以及在工作中的应用Promise的概念背景知识JavaScript的同步和异步JavaScript事件循环回调函数进行异步操作解决方案:PromisePromise 在工作中的运用创建PromisePromise封装AJAXPromise链式操作Promise.all()Promise.race()async和await总结Promi…

浅谈对Promise的理解以及在工作中的应用

  • Promise的概念
    • 背景知识
    • JavaScript的同步和异步
    • JavaScript事件循环
    • 回调函数进行异步操作
    • 解决方案:Promise
  • Promise 在工作中的运用
    • 创建Promise
    • Promise封装AJAX
    • Promise链式操作
    • Promise.all()
    • Promise.race()
    • async和await
  • 总结

Promise的概念

在开始讲解Promise前,我们先大致了解一下js的运行机制以及多个任务是怎么运作的。

背景知识

众所周知,JavaScript是一门单线程语言,也就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着,这样会造成浏览器处于假死状态,严重影响用户体验。为了解决这个问题,js引入了异步的概念,在执行任务时挂起处于等待中的任务,先运行排在后面的任务。等到刚才挂起的任务返回了结果,再回过头,把挂起的任务继续执行下去。于是,js将所有的任务分成了两种,一种是同步任务synchronous),另一种是异步任务asynchronous)。

JavaScript的同步和异步

同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行;
除了广义的同步任务和异步任务,对任务更精细的定义:

宏任务(macro-task):包括整体代码script,setTimeout,setInterval
微任务(micro-task):Promise,process.nextTick

宏任务中有微任务,一定要将宏任务中的微任务执行完毕,再去执行下一个宏任务
那究竟什么是任务队列呢,同步任务和异步任务又是怎么执行的,这就要引入js的运行机制:事件循环(event loop)

JavaScript事件循环

在这里插入图片描述
js事件循环运作机制如下:

  1. 同步任务和异步任务分别进入不同的“场所”,同步任务进入主线程,异步任务进入Event Table (事件表)并注册函数
  2. 指定的事件完成后,Event Table (事件表)会将这个函数移入到Event Queue (事件队列)
  3. 当主线程的任务完成后,会检查Event Queue (事件队列),如果有任务就全部执行,如果没有就进入下一个宏任务
  4. 这个过程会不断的重复,这就叫事件循环

回调函数进行异步操作

和同步操作不同,异步操作是不会立即返回结果的(如发起网络请求,下载文件,操作数据库等)。如果我们后续的函数需要之前返回的结果,又怎样使之前的异步操作在其完成时通知到后续函数来执行呢?

通常,我们可以将这个函数先定义,存储在内存中,将其当做参数传入之前的异步操作函数中,等异步操作结束,就会调用执行这个函数,这个函数就叫做回调函数(callback)

// 下载
function download(callback){// 模拟异步操作setTimeout(function(){// 调用回调函数callback('下载完成');}, 1000);
}function callback(value){// 下载完成的处理console.log(value);
}download(callback);// 这段代码将在1秒后在控制台打印“下载完成”

但假如callback函数同样是个异步函数,且callback里又嵌入了callback呢? 例如需求是等待第一个文件下载完成后,再下载第二个文件,等待第二个文件下载完成后,再下载第三个文件…,这样的话,上面这种方法就不可取了,因为会产生很多的函数嵌套,嵌套太深容易引发回调地狱(指的是回调函数里嵌套回调函数,使得代码可读性非常差,容易陷于无止尽的循环)

     //回调地狱setTimeout(function () {  //第一层console.log('张三');//等3秒打印张三在执行下一个回调函数setTimeout(function () {  //第二层console.log('李四');//等2秒打印李四在执行下一个回调函数setTimeout(function () {   //第三层console.log('王五');//等一秒打印王五}, 1000)}, 2000)}, 3000)

解决方案:Promise

所以为了回调地狱的问题,promise方案应运而生,它是对回调方法的一种封装,是用来处理异步操作的,可以让我们写异步调用的时候写起来更加优雅,更加美观。
以下是promise的一些特点

  1. Promise 对象代表一个异步操作,对象的状态不受外界影响,有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败)、settled (结束)只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,且一旦状态改变就不可再变
  2. Promise对象的then方法用来接收处理成功时响应的数据,catch方法用来接收处理失败时相应的数据,其中then方法的两个参数是resolve(成功回调),reject(失败回调)。异步任务执行成功时调用resolve函数返回结果,反之调用reject,根据不同的任务,由开发者来决定resolve和reject在函数体内的位置
  3. then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then/catch方法,链式调用可以保证代码的执行顺序
    promise解决刚才的地狱回调问题:
// promise解决方式
function fn(str) {var promise = new Promise(function (resolve, reject) { //resolve是成功的方法  reject是失败的方法  //处理异步任务var flag = true;setTimeout(function () {if (flag) {resolve(str)}else {reject('失败')}})})return promise;
}fn('张三').then((res) => { //then是成功执行的方法 返回的还是一个promise对象console.log(res);//打印张三  res是结果return fn('李四');}).then((res) => {console.log(res);return fn('王五')}).then((res) => {console.log(res);}).catch((res) => { //catch是失败执行的方法console.log(res);})

Promise 在工作中的运用

创建Promise

promise构造器只接收一个参数,该参数被称为执行器(executor)的函数。该函数会被传递两个参数(方法),一个叫做resolve,另一个叫做reject。

resolve函数在成功时调用,reject函数在失败时被调用。并且resolve和reject只能被使用一次,如果之后还有resolve和reject也不会被执行了,有点儿类似于return,但是不同点在于,其他代码还会被照常执行。

new Promise((resolve, reject)=> {resolve('我是第一次调用resolve');console.log('我是其他代码');resolve('我是第二次调用resolve'); // 不在起作用reject('我来调用reject'); // 不在起作用
})

也可以直接使用Promise.resolve或者Promise.reject来创建成功或者失败的Promise

let p1 = Promise.resolve('我是成功的Promise'),p2 = Promise.reject('我是失败的Promise');

Promise封装AJAX

var ajax = function(url) {return new Promise(function(resolve, reject) {var xhr = new XMLHttpRequest();xhr.open('get', url, true);xhr.send();xhr.onreadystatechange = function() {if (xhr.readystate == 4 && xhr.status == 200) {resolve(xhr.responseText)} else if (xhr.readystate == 4 && xhr.status !== 200) {reject(xhr.statusText)}}})
}
ajax.then(console.log(xhr.responseText)); //打印出返回的数据

Promise链式操作

由于Promise的then 方法始终返回一个 Promise 对象, 所以Promise 可以一直调用 then 方法,从而实现链式调用(解决地狱回调)。不管 new Promise 创建出来的执行状态是成功 / 失败,只要在 then / catch方法中通过 return 返回一个结果,不管这个值是 Promise 对象还是普通值,都可以通过链式调用的 .then 方法中获取到这个值,因为 promise.then 方法会默认在返回值的外层包裹一层 Promise 对象,这样才可以实现 Promise 一直通过 .then 的方式去链式调用

let p1 = new Promise((resolve, reject)=> {let name = '张三'setTimeout(()=> {resolve(name);}, 2000)
})let p2 = new Promise((resolve, reject)=> {let name = '李四'setTimeout(()=> {resolve(name);}, 1000)
})let p3 = new Promise((resolve, reject)=> {let name = '王五'setTimeout(()=> {resolve(name);}, 3000)
})//方式一:链式操作返回promise对象
p1.then((res) => {console.log(res+'第一个出场');return p2
}).then((res) => {console.log(res+'第二个出场');return p3
}).then((res) => {console.log(res+'第三个出场');
})//链式操作返回promise对象输出结果
张三第一个出场
李四第二个出场
王五第三个出场//方式二:链式操作返回普通值
p1.then((res) => {console.log('我是'+res);return res
}).then((res) => {console.log('我是'+res+'的儿子');return res
}).then((res) => {console.log('我是'+res+'的孙子');
})//链式操作返回普通值输出结果
张三第一个出场
李四第二个出场
王五第三个出场

Promise.all()

这个方法返回一个新的promise对象,该promise对象在参数对象promises里所有的promise对象都成功的时候才会触发成功,一旦有任何一个promises里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含promises里所有promise返回值的数组作为成功回调的返回值,顺序跟promises的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。
简而言之,all方法会将传入的异步操作并行执行,等到它们都执行完后才会进到then方法,从时间上来看取决于最后一个异步任务执行完成的时间

let p1 = new Promise((resolve, reject)=> {let name = '张三'setTimeout(()=> {resolve(name);}, 2000)
})let p2 = new Promise((resolve, reject)=> {let name = '李四'setTimeout(()=> {resolve(name);}, 1000)
})let p3 = new Promise((resolve, reject)=> {let name = '王五'setTimeout(()=> {resolve(name);}, 3000)
})// promise.all用法
Promise.all([p1,p2,p3]).then((res) => {console.log(res+'都已到达终点');
})// promise.all输出结果
张三,李四,王五都已到达终点

Promise.race()

race就是赛跑的意思,谁先出结果就由谁决定,采用第一个 promise 的值作为它的值,当promises参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。

let p1 = new Promise((resolve, reject)=> {let name = '张三'setTimeout(()=> {resolve(name);}, 2000)
})let p2 = new Promise((resolve, reject)=> {let name = '李四'setTimeout(()=> {resolve(name);}, 1000)
})let p3 = new Promise((resolve, reject)=> {let name = '王五'setTimeout(()=> {resolve(name);}, 3000)
})// promise.race用法
Promise.race([p1,p2,p3]).then((res) => {console.log(res+'第一个到达终点');
})// promise.all输出结果
李四第一个到达终点

async和await

async 是“异步”的简写,而 await 可以认为是 async wait(等待) 的简写。
所以应该很好理解 async 用于申明一个 function 是异步的,返回的是一个 Promise 对象.
而 await 用于等待一个异步方法执行完成,后面必须跟一个Promise对象,但是不必写then(),直接就可以得到返回值


//基本用法的async函数
let asyncFun = async function(){return 1
}
console.log(asyncFun())
//会返回一个promise对象//使用场景
//摇色子方法
function dice(){return new Promise((resolve,reject)=>{let sino = parseInt(Math.random()*6+1)  //生成一个1~6之间的随机小数setTimeout(()=>{resolve(sino)},2000)})
}
//异步方法async function text(){let n= await dice()//await 关键字后面调用摇色子方法执行完毕之后,才进行变量赋值console.log("摇出来"+n)  //最后打印出摇出来的数}
text()//输出结果
Promise { 1 }
摇出来5

总结

以上就是我个人关于Promise的理解以及在工作中的应用,总的来说Promise在日常开发工作中的使用还是比较多的,他最大的用途在于让多个异步的任务按照我们想要的方式去执行。但想要彻底理解promise的运行方式及原理,还需要了解js引擎的运行逻辑,任务队列、宏任务微任务等。上文中如果有错误的地方欢迎指正,大家共同进步,越秃越强!

http://www.zhongyajixie.com/news/28997.html

相关文章:

  • 做网站的基本知识宁波网站建设公司哪家好
  • 深圳做企业网站哪家好什么是竞价
  • 昆明网站seo全网推广软件
  • wordpress占用优化大师好用吗
  • 龙岩论坛拼多多关键词优化是怎么弄的
  • 阿里巴巴做网站吗网络平台推广运营有哪些平台
  • 网上商店的优势和缺陷免费的电脑优化软件
  • 怎样做艾条艾柱网站微信软文怎么写
  • 做酒店网站设计最新疫情19个城市封城
  • 网站开发论文中期检查表关键词热度
  • 2017网站seo如何做刷关键词排名seo软件软件
  • 建网站知乎福州网站优化
  • 微山网站建设公司网络推广方式有哪些
  • 免费网站制作平台下载b2b平台
  • 《学做网站论坛》视频下载谷歌seo是什么意思
  • 网站建设都需要什么文案新手怎么做电商
  • 做一斗地主网站多少钱域名状态查询工具
  • wordpress模板建站企业员工培训总结
  • 建设假网站手机网站关键词快速排名
  • 成都网站建设 好多科技手机优化器
  • 推广营销外包合肥seo软件
  • 品牌设计公司企业vi设计适合seo的建站系统
  • 什么网站百度的收录高培训机构加盟
  • 企业怎么在网站上做宣传郑州网站设计有哪些
  • 网站空间商是什么意思网站推广在线推广
  • 高校后勤网站建设谷歌账号
  • 河南郑州哪里可以做公司网站如何制作微信小程序
  • 住房和城乡建设部网站 绿地网络营销软件
  • 山东正元建设网站seo双标题软件
  • 网站导航效果哪些浏览器可以看禁止访问的网站