在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、promise描述promise是javascript中标准的内置对象,用于表示一个异步操作的最终状态(是失败还是成功完成)及其结果值。它让你能够把异步操作最终成功或者失败的原因和响应的处理程序相关联,也就是说通过promise你可以自定义异步操作结束后该做什么。这样的话异步方法就和同步方法很类似,也有返回值,只不过这个返回值不是立即返回最终的值,而是返回一个promise,当promise的状态发生改变时,就会触发相应的处理程序。 一个promise无论什么时候都必然处于以下几种状态:1、待定(pending) 2、已兑现(fulfilled) 3、已拒绝(rejected) promise创建之初是待定状态,它既咩有被兑现也咩有被拒绝,它用于包装还没有被添加promise支持的函数,包装后的函数变成异步操作函数,当操作结束时,会有两个两个分支,一个是已兑现,一个是已拒绝,如下图。已兑现状态的promise会调用后续的then方法,而已拒绝状态的promise既可以调用then方法,也可以被catch方法捕捉到。为什么then方法可以捕捉两个状态的promise呢?这里先不讲,下面再详细介绍。 二、promise 的流程走向上图是promise的流程图,从左到右可以得知一个promise在待定状态时通过两个分支走向分别进入then方法或者catch方法,这两个c方法都会返回promise,如果这个promise也被敲定了,而且其后也有then方法或者catch方法,则又会进入后续的then和catch中,直至咪有。 也就是说,promise和then或者catch可以形成一个异步操作的链式结构,结合js的事件循环机制,这使得js的优势更加明显,发展至今仍能在浏览器上频繁看到它的身影。 我们要注意流程的特点: 1、promise是对象,它的转移成功不取决于返回值,而取决于状态的敲定(是成功还是失败) 2、then和catch是函数,只要有promise状态发生了改变,该promise对应后面的then或者catch方法就会被调用,而这两个方法本身会返回一个promise,这个返回的promise又会影响这两个方法后面的then或者catch方法。两个方法的返回值一定是promise。 三、promise的创建
let myFirstPromise = new Promise(function(resolve, reject){ //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...) //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法. setTimeout(function(){ resolve("成功!"); //代码正常执行! }, 250); }); myFirstPromise.then(function(successMessage){ //successMessage的值是上面调用resolve(...)方法传入的值. //successMessage参数不一定非要是字符串类型,这里只是举个例子 console.log("Yay! " + successMessage); }); 四、promise的优势在promise未出现时,如果我们调用异步代码块的话是没有办法保持顺序的,而如果又出现了异步代码结果之间按序的需求,该如何实现呢? 以前的话通常都会将异步代码一层一层地内嵌来实现异步代码按序实现,但是这就造成了代码维护困难,开发难度增大 doSomething(function(result) { doSomethingElse(result, function(newResult) { doThirdThing(newResult, function(finalResult) { console.log('Got the final result: ' + finalResult); }, failureCallback); }, failureCallback); }, failureCallback); 这就是经典的回调地狱。而如果使用了前面介绍的promise,那么代码就变成了容易维护的链式结构 五、then方法返回的promise类型当一个
六、catch捕捉的错误catch能捕捉promise组合中出现的错误,但是有两种错误不能捕捉: 1、已决议的错误不能捕捉 //创建一个新的 Promise ,且已决议 var p1 = Promise.resolve("calling next"); var p2 = p1.catch(function (reason) { //这个方法永远不会调用 console.log("catch p1!"); console.log(reason); }); p2.then(function (value) { console.log("next promise's onFulfilled"); /* next promise's onFulfilled */ console.log(value); /* calling next */ }, function (reason) { console.log("next promise's onRejected"); console.log(reason); }); 2、异步函数中抛出的错误不能捕捉 需要注意的是,作者亲手实践发现:promise包裹的异步函数执行成功后必须显式地调用resolve和reject方法才能触发后续then和catch方法,如果promise方法包裹的不是异步函数,是普通的同步函数,如果该同步代码运行出错,即便没有调用reject方法时,后面的catch方法仍然能够捕捉到这个错误,但如果同步代码没有出错,没有显式调用resolve方法转移的话,后续的then方法不会触发。 七、高级示例<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 10px; } html{ width: 100%; height: 100%; } body{ width: 100%; height: 100%; display:flex; align-items: center; justify-content: center; } div.displaydatabox{ width: 300px; height: 300px; border-radius: 50px; text-align: center; line-height: 300px; box-shadow: 0 0 10px 2px black; } div.button{ width: 100px; height: 50px; border-radius: 21px; border: 2px solid orange; line-height: 50px; text-align: center; cursor: pointer; } </style> </head> <body> <div class="button">创建</div> <div class="button">输入文字</div> <div class="button">消失</div> <script lang="javascript"> let buttonlist=document.querySelectorAll("div.button"); let body=document.querySelector("body"); buttonlist[0].onclick=function() { let div=document.createElement("div"); div.className="displaydatabox"; body.appendChild(div); } buttonlist[2].onclick=function() { let div=document.querySelector("div.displaydatabox"); body.removeChild(div); } buttonlist[1].onclick=function(e) { let p1=new Promise((resolve,reject)=> { setTimeout(()=>{//用setTimeout函数模拟异步函数 let div=document.querySelector("div.displaydatabox"); div.textContent="这是promise实验"; //reject(1); resolve(1);//调用resolve将调用第一个then },2000); }).then(function(resolve){ return new Promise((resolve,reject)=>{ console.log("这是状态咩有敲定的promise,所以不会调用后面所有的then方法"); //resolve(1)//没有调用resolve或者reject,所以状态未敲定。如果调用,将输出1和finally it has been called!! }) .then(function(e){ console.log(e); }); }).catch(function(e) { console.log(e+" 没有块可以输入!!"); }).then(()=> { console.log("finally it has been called!!"); }) } </script> </body> </html> 到此这篇关于关于javascript中的promise的用法和注意事项的文章就介绍到这了,更多相关js中promise用法内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论