用浅显方式说明 Javascript 的 Promise

前言:最近在研究串接资料,刚好学习到了一个ES6的新用法,先来记录说明一下。

在此之前我们还要了解什么是同步与非同步

同步(synchronous):发一个请求,就要等待服务器的响应结束,然后才能发第二请求!中间这段时间就是 loading ;刷新的是整个页面。

异步(asynchronous):发一个请求后,无需等待服务器的响应,然后就可以发第二个请求!可以使用 Javascript 接受服务器的响应,然后使用 Javascript 来局部刷新。

来个比较如下:

Asyncsyncone at a timemore one at a time执行了就马上换下一个指令第一个执行完才执行下一个

Async Actions

click, AJAX, SetInterval解决方法, callback , promises, async await (这一次不讨论,因为他是promises 的简写)

先说说callback,就是在function里面再执行一个function
这是目前传统用法来解决同步非同步的事情。

var btn =document.querySelector('#btn');var doIt = function() {  alert("you triggered " + this.id);};btn.addEventListener("click", doIt);

我们可以说 doIt 就是一个 callback 函式,

回到今天想要讲的 Promise :100:

ES6新语法Promise 物件代表一个即将完成、或失败的非同步操作,
以及它所产生的值。return resolve or reject (用到了两个参数)ES6 Promise的实作中,会确保Promise物件一实体化后就会固定住状态,要不就是"已实现",要不就是"已拒绝"

附注:resolve 和 reject 是参数
大概会是长像下面一样:

const promise = new   Promise(function(resolve, reject) {     // 成功时     resolve(value)     // 失败时     reject(reason) }); promise.then(function(value) {     // on fulfillment(已实现时) }, function(reason) {     // on rejection(已拒绝时) })//http://eddychang.me/blog/javascript/88-promise-basic-usage.html

记住我们为什么要把 Promise 用在 Ajax 上面:

Ajax 是属于一个透过 JavaScript 技术名称,用于取得远端资料;而 Promise 则是一个语法,专门用来处理非同步行为,并不是专门用来处理 Ajax 使用,所以两者是不同的。

中文翻译意思:

如果想等 A 结束之后再进行 B..?

用一个生活化例子就是,我们去百货公司美食街吃东西,点完餐店员会给你一个小圆盘,等那圆盘动了,就可以去拿吃的。
结果成功就是 resolve ,失败了就是rejected

Promise:

如果成功的话... 如果失败的话...
(resolve)<--> (reject)

先备知识:
函式建构式要先了解比较好喔!
JavaScript 建构式

new Promise 代表的是建立一个 Promise 物件,function(resolve, reject){} 代表的是建构式里面包含的执行函式( executor function ),执行函式包含,resolve、reject,这两个函式作为参数,当事件成功时便会回传 resolve 里面的值,反之当事件失败便会回传 reject 里面的值。

接下来说个例子,
我们先设定攻击的大绝招,成功之后(resolve) 会发生什么事

let Bigtrick =  new Promise( (resolve,reject)=>{  // 可能是⼀个需要花时间的动作..  setTimeout(()=> resolve('火之呼吸'),3000);  // setTimeout(function resolve(){  //     resolve('火之呼吸');  //   },3000)  });
Bigtrick  .then((skill)=>console.log(`使用招式:${skill}`)) //promise成功  .catch((err)=>console.log(`${err}无法使用`))//promise失败

Bigtrick().then 的 then 代表了可以接收 Bigtrick() 这个 Promise 完成时,可以接受到回传的值,如果回传的值为错误时,则可以用 .catch 去做错误的值接收,.then 是可以一直串接下去的。这个行为叫做 Promise Chain

setTimeout()用法

MDN 定义 setTimeout() 的作用 是在延迟了某段时间 (单位为毫秒) 之后,才去执行「一次」指定的程式码

接下来製作一个小游戏,
範例网址
点击一个按钮连击 5次以上在三秒之内,成功执行后会产生招式名称。

我们先找到 按钮和印出画面的 dom,然后做出点击时会发生的事件:数字chi变数=点击次数出现在画面

let chi =0;let i =0;let hitButton =document.getElementById('hitButton');let result =document.getElementById('result');hitButton.onclick=function(e){  e.preventDefault();  chi +=1;  hitButton.innerHTML =`集气 ${chi}次 `;   }

那我们利用 new Promise()实作,要在三秒以内,点击数超过5次才会出现 水之呼吸(利用 setTimeout 方法)

  let bigSkill =new Promise((resolve,reject)=>{    setTimeout(()=>{      if(chi>=5){      resolve('水之呼吸!!');      }else{      reject('水之呼吸!!');            };    },3000); });

成功达成条件后(点击超过五次)resolve
就连上.then, 失败 reject 就是被 catch 接到

 bigSkill     .then( skill => result.innerHTML =`发动招式:${skill}`)     .catch( err => result.innerHTML =`${err} 无法使用`)

画面如下:
image

其实 promise 不是必要,在以前没有 promise 的时候也是可以做到非同步的事。在 promise 之前,可以用 callback 的方式来处理,但如果连续的处理的事情多,callback 就容易一层包一层,程式码会变得不容易阅读,俗称「callback hell」

这样是我真的对 callback function 怕怕的原因,函式包函式
,脑袋都要昏了。

而 promise 的出现,可以简化 callback 的流程,用 then .. then .. 的方式来解决 callback hell 的状况喔。

资料来源:

五倍速红宝石
使用 Promise 处理非同步
Promise 对象



关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章