关于javascript中的promise的用法和注意事项(推荐)

一、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的创建

Promise对象是由关键字new及其构造函数来创建的。该构造函数会把一个叫做“处理器函数”(executor function)的函数作为它的参数。这个“处理器函数”接受两个函数——resolvereject——作为其参数。当异步任务顺利完成且返回结果值时,会调用resolve函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject函数。示例如下:

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类型

当一个Promise完成(fulfilled)或者失败(rejected)时,返回函数将被异步调用(由当前的线程循环来调度完成)。具体的返回值依据以下规则返回。如果then中的回调函数:

  • 返回了一个值,那么then返回的 Promise 将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
  • 没有返回任何值,那么then返回的 Promise 将会成为接受状态,并且该接受状态的回调函数的参数值为undefined
  • 抛出一个错误,那么then返回的 Promise 将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
  • 返回一个已经是接受状态的 Promise,那么then返回的 Promise 也会成为接受状态,并且将那个 Promise 的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
  • 返回一个已经是拒绝状态的 Promise,那么then返回的 Promise 也会成为拒绝状态,并且将那个 Promise 的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
  • 返回一个未定状态(pending)的 Promise,那么then返回 Promise 的状态也是未定的,并且它的终态与那个 Promise 的终态相同;同时,它变为终态时调用的回调函数参数与那个 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用法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaScript中Promise的使用详解

    Promise是ES6中的函数,规范了如何处理异步任务的回调函数,功能类似于jQuery的defferred.简单说就是通过promise对象的不同状态调用不同的回调函数.目前IE8及以下不支持,其他浏览器都支持. promise对象的状态,从Pending转换为Resolved或Rejected之后,这个promise对象的状态就不会再发生任何变化. 使用步骤: var promise = new Promise(function(resolve, reject) { // 异步任务,通过调用

  • 理解JavaScript中Promise的使用

    Javascript 采用回调函数(callback)来处理异步编程.从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的回调金字塔(Pyramid of Doom),绝对是一种糟糕的编程体验.于是便有了 CommonJS 的 Promises/A 规范,用于解决回调金字塔问题.本文先介绍 Promises 相关规范,然后再通过解读一个迷你的 Promises 以加深理解. 什么是 Promise 一个 Promise 对象代表一个目前还不可用,但是在未来的

  • JavaScript中的Promise使用详解

    许多的语言,为了将异步模式处理得更像平常的顺序,都包含一种有趣的方案库,它们被称之为promises,deferreds,或者futures.JavaScript的promises ,可以促进关注点分离,以代替紧密耦合的接口. 本文讲的是基于Promises/A 标准的JavaScript promises.[http://wiki.commonjs.org/wiki/Promises/A] Promise的用例: 执行规则 多个远程验证 超时处理 远程数据请求 动画 将事件逻辑从应用逻辑中解耦

  • 举例详解JavaScript中Promise的使用

    摘录 – Parse JavaScript SDK现在提供了支持大多数异步方法的兼容jquery的Promises模式,那么这意味着什么呢,读完下文你就了解了. "Promises" 代表着在javascript程序里下一个伟大的范式,但是理解他们为什么如此伟大不是件简单的事.它的核心就是一个promise代表一个任务结果,这个任务有可能完成有可能没完成.Promise模式唯一需要的一个接口是调用then方法,它可以用来注册当promise完成或者失败时调用的回调函数,这在Common

  • 异步JavaScript编程中的Promise使用方法

    异步? 我在很多地方都看到过异步(Asynchronous)这个词,但在我还不是很理解这个概念的时候,却发现自己常常会被当做"已经很清楚"(* ̄? ̄). 如果你也有类似的情况,没关系,搜索一下这个词,就可以得到大致的说明.在这里,我会对JavaScript的异步做一点额外解释. 看一下这段代码: var start = new Date(); setTimeout(function(){ var end = new Date(); console.log("Time elap

  • JS 中使用Promise 实现红绿灯实例代码(demo)

    要求 使用promise 实现红绿灯颜色的跳转 绿灯执行三秒后 黄灯执行四秒后 红灯执行五秒 html 实现如下: <ul id="traffic" class=""> <li id="green"></li> <li id="yellow"></li> <li id="red"></li> </ul> 定义一个

  • 详细解读JavaScript编程中的Promise使用

    Promise核心说明 尽管Promise已经有自己的规范,但目前的各类Promise库,在Promise的实现细节上是有差异的,部分API甚至在意义上完全不同.但Promise的核心内容,是相通的,它就是then方法.在相关术语中,promise指的就是一个有then方法,且该方法能触发特定行为的对象或函数. Promise可以有不同的实现方式,因此Promise核心说明并不会讨论任何具体的实现代码. 先阅读Promise核心说明的意思是:看,这就是需要写出来的结果,请参照这个结果想一想怎么用

  • 关于javascript中的promise的用法和注意事项(推荐)

    一.promise描述 promise是javascript中标准的内置对象,用于表示一个异步操作的最终状态(是失败还是成功完成)及其结果值.它让你能够把异步操作最终成功或者失败的原因和响应的处理程序相关联,也就是说通过promise你可以自定义异步操作结束后该做什么.这样的话异步方法就和同步方法很类似,也有返回值,只不过这个返回值不是立即返回最终的值,而是返回一个promise,当promise的状态发生改变时,就会触发相应的处理程序. 一个promise无论什么时候都必然处于以下几种状态:1

  • 深入学习JavaScript中的promise

    目录 为什么要用Promise? 使用Promise解决异步控制问题 Promise的结构 回调函数 为什么异步代码一定是回调函数结构? 刨析Promise 原型方法——catch\finally\then 为什么要在.then的回调函数中return一个Promise呢? 那如果我们不指明return返回值,它会返回什么呢?是如何实现链式调用呢? resolve和reject resolve() reject() Promise常用API——all().allSettled().any().r

  • JavaScript中日常收集常见的10种错误(推荐)

     1 对于this关键词的不正确使用 Game.prototype.restart = function () { this.clearLocalStorage(); this.timer = setTimeout (function() { this.clearBoard(); }, 0); }; 运行上面的代码将会出现如下错误: uncaught typeError:undefined is not a function 为什么会有这个错? this是指代当前对象本身,this的调用和它所在

  • JavaScript中数组的22种方法必学(推荐)

    前面的话 数组总共有22种方法,本文将其分为对象继承方法.数组转换方法.栈和队列方法.数组排序方法.数组拼接方法.创建子数组方法.数组删改方法.数组位置方法.数组归并方法和数组迭代方法共10类来进行详细介绍 对象继承方法 数组是一种特殊的对象,继承了对象Object的toString().toLocaleString()和valueOf()方法 [toString()] toString()方法返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串 [注意]该方法的返回值与不使用任何参数

  • JavaScript中的一些隐式转换和总结(推荐)

    js中的不同的数据类型之间的比较转换规则如下: 1. 对象和布尔值比较 对象和布尔值进行比较时,对象先转换为字符串,然后再转换为数字,布尔值直接转换为数字 [] == true; //false []转换为字符串'',然后转换为数字0,true转换为数字1,所以为false 2. 对象和字符串比较 对象和字符串进行比较时,对象转换为字符串,然后两者进行比较. [1,2,3] == '1,2,3' // true [1,2,3]转化为'1,2,3',然后和'1,2,3', so结果为true; 3

  • JavaScript中内存泄漏的介绍与教程(推荐)

    本文主要给大家详细介绍了关于JavaScript中内存泄漏的相关内容,文中介绍的非常详细,对大家具有一定的参考学习价值,下面来一起看看详细的介绍: 一.什么是内存泄漏? 程序的运行需要内存.只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存. 对于持续运行的服务进程(daemon),必须及时释放不再用到的内存.否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃. 不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak). 有些语言(比如 C 语言)必须手动

  • JavaScript中的Promise详解

    目录 Promise的基本用法: 1.创建Promise对象 2.Promise 方法 总结 Promise是异步编程的一种解决方案,是一个对象,可以获取异步操作的消息,大大改善了异步编程的困难,避免了回调地狱,比传统的解决方案回调函数和事件更合理和更强大. 从语法上讲,Promise是一个对象,它可以获取异步操作的消息.提供了一个统一的API,各种异步操作都可以用同样的方法进行处理 1.Promise的实例有三个状态: (1)Pending(进行中) (2)Resolved(已完成) (3)R

  • javascript中的107个基础知识收集整理 推荐

    1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body) 4.一个浏览器窗口中的DOM顺序是:window->(navigator,screen,history,location,document) 5.得到表单中元素的名称和值:document.getElementById("表单中元素的ID号").name(或value) 6.一个小写转大

  • javascript中Promise使用详解

    目录 一.首先,要知道为什么要用Promise语法? 二.接着,来了解一下回调地狱(Callback Hell) 三.最后,也是本章的重头戏,Promise的基本使用 (一) resolve函数 (二) rejected函数 (三)Promise的API 1. then 2. catch 3. finally 4. Promise.all 5. Promise.race 四.最后 前言: 做过前端开发的都知道,JavaScript是单线程语言,浏览器只分配给JS一个主线程,用来执行任务,但是每次

随机推荐