前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES6异步处理解决方案

ES6异步处理解决方案

作者头像
javascript艺术
发布2021-05-28 14:06:12
7600
发布2021-05-28 14:06:12
举报
文章被收录于专栏:javascript艺术javascript艺术

ES6的异步处理模型分为俩个阶段三种状态。

两个阶段:未决unsettled, 已决settled。

三个状态:pending挂起状态 , resolved成功, rejected失败

通常把从未决推向已决的resolved状态的过程叫做resolve,从未决推向已决的rejected状态的过程,叫做reject

任务已决状态后可能需要后续处理,若任务成功了(resolved),有后续处理,如果任务失败了(rejected),仍然有后续处理,把针对resolved的后续处理,称为thenable,针对rejected的后续处理,称为catchable;

针对resolved的后续处理我们称之为thenable

针对rejected的后续处理我们称之为catchable


Promise 对象
什么是Promise

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

Promise对象有以下两个特点。

1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。

2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

Promise用法

ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。

代码语言:javascript
复制
const task = new Promise((resolve, reject) => {     
    // 任务未决阶段代码  
    // 立即执行  
    console.log("开始");  
    setTimeout(() => {  
       if (Math.random() > 0.5) {  
           // 成功 
           // 推向成功  
           resolve("成功");  
       } else {  
           // 失败 
           // 推向失败  
           reject("失败");  
       }  
    }, 1000)
});
task.then((result) => {
  console.log(result);
}).catch((error) => {
  console.log(error);
})

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise.prototype.then()

then方法是定义在原型对象Promise.prototype上的。then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数。then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

代码语言:javascript
复制
getJSON("/posts.json").then(function(json) {
  return json.post;
}).then(function(post) {
  // ...
});

采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

Promise.prototype.catch()

如果异步操作抛出错误,状态就会变为rejected,就会调用catch()方法指定的回调函数,处理这个错误。另外,then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。

catch方法返回的还是一个 Promise 对象。

代码语言:javascript
复制
getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // 处理 getJSON 和 前一个回调函数运行时发生的错误
  console.log('发生错误!', error);
});
Promise.prototype.finally()

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

代码语言:javascript
复制
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
Promise.prototype.all()

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

代码语言:javascript
复制
const p = Promise.all([p1, p2, p3]);

p的状态由p1、p2、p3决定,分成两种情况。

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

Promise.race()

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

代码语言:javascript
复制
const p = Promise.race([p1, p2, p3]);

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

async/await

async函数在function前面有个async作为标识,意思就是异步函数,里面有个await搭配使用,每到await的地方就是程序需要等待执行后面的程序,语义化很强。

  • await只能在async函数中使用
  • await后面的语句可以是promise对象、数字、字符串等
  • async函数返回的是一个Promsie对象
  • await语句后的Promise对象变成reject状态时,那么整个async函数会中断,后面的程序不会继续执行
  • async中如果没有return,返回值是Promise,但是没有值;async中如果有return,return的值会作为返回Promise的then的值
代码语言:javascript
复制
async function getStockPriceByName(name) {
  const symbol = await getStockSymbol(name);
  const stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

getStockPriceByName('goog').then(function (result) {
  console.log(result);
});
错误处理

try/catch/finally 语句用于处理代码中可能出现的错误信息。

  • try语句允许我们定义在执行时进行错误测试的代码块。
  • catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
  • finally 语句在 try 和 catch 之后无论有无异常都会执行。

注意 :catch 和 finally 语句都是可选的,但你在使用 try 语句时必须至少使用一个。

提示 :当错误发生时, JavaScript 会停止执行,并生成一个错误信息。使用 throw 语句 来创建自定义消息(抛出异常)。如果你将 throw 和 try 、 catch一起使用,就可以控制程序输出的错误信息。

代码语言:javascript
复制
async function main() {
  try {
    const val1 = await firstStep();
    const val2 = await secondStep(val1);
    const val3 = await thirdStep(val1, val2);

    console.log('Final: ', val3);
  }
  catch (err) {
    console.error(err);
  }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 javascript艺术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Promise 对象
    • 什么是Promise
      • Promise用法
        • Promise.prototype.then()
          • Promise.prototype.catch()
            • Promise.prototype.finally()
              • Promise.prototype.all()
                • Promise.race()
                • async/await
                  • 错误处理
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档