js的三种异步处理

Promise 对象

  • 含义: Promise是异步编程的一种解决方案,
  • 优点: 相比传统回调函数和事件更加合理和优雅,Promise是链式编程(后面会详细讲述),有效的解决了令人头痛的回调地狱问题,Promise的结果有成功和失败两种状态,只有异步操作的结果,可以决定当前是哪一种状态,外界的任何操作都无法改变这个状态
  • 基本用法:
    //ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。
    const p = new Promise(function(resolve,reject){
        if(success){
            resolve(‘成功的结果‘)
        }else{
            reject(‘失败的结果‘)
        }
    })
    p.then(function (res) {
        // 接收resolve传来的数据,做些什么

    },function (err) {
        // 接收reject传来的数据,做些什么
    })
    p.catch(function (err) {
        // 接收reject传来的数据或者捕捉到then()中的运行报错时,做些什么
    })
    p.finally(function(){
        // 不管什么状态都执行
    })
  • 常用API

    • resolve 返回异步操作成功的结果
    • reject 返回异步操作失败的结果
    • then 执行Promise状态是成功的操作
    • catch 执行Promise状态是失败的操作
    • finally 不管Promise状态是成功或失败都执行的操作
  • Promise.all
    • Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
    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的回调函数。

Generator 函数

  • 含义: Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同,
    • 基本用法:
    function* helloGenerator() {
      yield ‘hello‘;
      yield ‘Generator‘;
      return ‘over‘;
    }

    let hw = helloGenerator();
    hw.next()//{value:"hello",done:false}
    hw.next()//{value:"Generator",done:false}
    hw.next()//{value:"over",done:true}
    hw.next()//{value:undfined,done:true}
  • 特征:

    • 一是,function关键字与函数名之间有一个星号;
    • 二是,函数体内部使用yield表达式,定义不同的内部状态;
    • 三是,通过next方法获取每段状态的返回结果,上面分成4次执行了Gennrator函数,第一次,获取第一个yield函数的返回结果并暂停,done:false,代表函数内的状态还没有执行结束;第二次,同理;第三次,获取return 的返回结果,done:true表示函数内的状态已经执行完毕;第四次,函数内已经没有可以执行的状态,所有返回undfined,同时告诉函数内的状态已经执行完毕;如果函数内没有return,在第三次时返回undfined,done:true表示函数内的状态已经执行完毕

async 函数

  • 含义: async 函数是在ES2017 标准中引入的,async使得异步操作变得更加方便,其实他就是Generator 函数的语法糖
  • 基本用法:
    function get1(){
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{resolve(1)},2000)

        })
    }
    async function getSet(){
        const n = await get1()
        //const n = await ‘111‘
        return n
    }
    getSet().then(console.log)
  • 说明:

    • await命令只能用在async函数之中,如果用在普通函数,就会报错。
    • await后面是一个Promise对象,如get1 return出去的Promise实例;如果不是 Promise 对象,就直接返回对应的值,如直接返回‘111‘。
      • 1、若Promise 对象, 并且其以值 x 被 fulfilled, 则返回值为 x.
      • 2、Promise 对象, 并且其以异常 e 被 rejected, 则抛出异常 e
    • async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,如果任何一个await语句后面的 Promise 对象变为reject状态或遇到return,那么整个async函数都会中断执行。
    • 另外需要注意的是, await 在等待 Promise 对象时会导致 async function 暂停执行, 一直到 Promise 对象决议之后才会 async function 继续执行.
    • 如果我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。
    async function f() {
        try {
            await Promise.reject(‘出错了‘);
        } catch(e) {
        }
        return await Promise.resolve(‘hello world‘);
    }

    f().then(v => console.log(v))
  • 优点: 相比Generator函数,async函数有如下四点改进

    • 内置执行器: Generator 函数的执行必须靠next()进行每一次的模块执行,async自带执行器,只需要和普通函数一样调用即可执行
    • **更好的语义:**async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
    • 返回值是Promise: async函数的返回值是 Promise 对象,可以用then方法指定下一步的操作;而且async函数完全可以看做多个异步函数的操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖,即Promise.all()的用法
    • **更广的适用性:**相较于Generator函数async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)
  • 补充
    • 多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
    //此处省略getFoo(), getBar()两个函数

    // 写法一
    async function getSet(){
        let [foo, bar] = await Promise.all([getFoo(), getBar()]);
        return [foo, bar]
    }

    // 写法二
    async function getSet(){
        let fooPromise = getFoo();
        let barPromise = getBar();
        let foo = await fooPromise;
        let bar = await barPromise;
        return [foo, bar]
    }

*文章参考ECMAScript 6 入门 *

原文地址:https://www.cnblogs.com/mouseleo/p/10801665.html

时间: 2024-08-01 12:41:52

js的三种异步处理的相关文章

Js的三种条件判断语句

Js的三种条件判断语句 If if语句 只有当指定条件为 true 时,使用该语句来执行代码. 语法 if (条件) { 只有当条件为 true 时执行的代码 } if...else 语句 在条件为 true 时执行代码,在条件为 false 时执行其他代码. 语法 if (条件) { 当条件为 true 时执行的代码 } else { 当条件不为 true 时执行的代码 } If...else if...else 语句 使用 if....else if...else 语句来选择多个代码块之一来

JS的三种使用方式/CSS的三种使用方式/JS中的DOM事件模型/JS中匿名函数的书写及调用/媒体查询@media的三种使用方式

一.JS的三种使用方式 1.html标签中内嵌JS(不提倡使用.)                <button onclick="javascript:alert('你真点啊.')" > 有本事点我呀!!!!</button>                                2.HTML页面中直接使用JS:                <script type="text/javascript">        

js默认三种弹框方式

<!--js默认三种弹框方式--> <!--警告--><div onclick="alert('警告')">onclick!</div> <!--确认--><div onclick="confirm('确认')">onclick!</div> <!--信息输入--><div onclick="prompt('信息输入')">onclick!

js按钮确认删除提示以及js的三种弹出框简单介绍

js按钮确认删除提示 第一种方法: html代码: 1 <a href="" οnclick="javascript:return del();">删除</a> js代码: 1 function del() { 2 var msg = "您真的确定要删除吗?\n\n请确认!"; 3 if (confirm(msg)==true){ 4 return true; 5 }else{ 6 return false; 7 } 8

JS中三种字符串连接方式及其性能比较

工作中经常会碰到要把2个或多个字符串连接成一个字符串的问题,在JS中处理这类问题一般有三种方法,这里将它们一一列出顺便也对它们的性能做个具体的比较. 第一种方法  用连接符“+”把要连接的字符串连起来: str="a"; str+="b"; 毫无疑问,这种方法是最便捷快速的,如果只连接100个以下的字符串建议用这种方法最方便. 第二种方法  以数组作为中介用 join 连接字符串: var arr=new Array(); arr.push(a); arr.push

简述三种异步上传文件方式

 很久没写过博客了! 上次写已经是去年的12月了,离现在也有足足三个月了.这几个月因为要搭建个人网站以及准备个人简历,包括最近要准备最近的各大公司的实习春招,很难抽时间来写博客,这次的异步文件上传我觉得是很有必要了解的,笼络了很多知识点,因此准备写一篇博客来巩固下. 异步上传文件是为了更好的用户体验,是每个前端必须掌握的技能.这里我提出三点有关异步文件上传的方式. 使用第三方控件,如Flash,ActiveX等浏览器插件上传. 使用隐藏的iframe模拟异步上传. 使用XMLHttpReques

应对加密js的三种方法

经常遇到网页在登录后会对用户输入的帐号和密码通过js进行加密,导致模拟登录这类网站时受到阻碍 这里小记一下当前解决该问题的三种方法 1.利用python实现js同等加密. 2.利用selenium模拟登录. 3.利用pyexecjs来执行js文件 测试站点:http://bbs.125.la/ 登录时通过浏览器F12发现该网站对密码进行了加密 进一步分析和查找,发现是名为md5.js?RFI文件进行了加密 尝试用第一种方法,但是发现此文件内容较多,通过python转换相应程序较为复杂,因此放弃

js的三种继承方式及其优缺点

第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = 'yellow'; this.view = function(){ return this.hair + ',' + this.eye + ',' + this.skin; } } //子类 function man(){ this.feature = ['beard','strong']; } man.pr

C# Thread、delegate、Task三种异步进行对比

1.Thread [线程] 不断创建 Thread 会消耗很大的cup 导致 异步效率变慢 2.delegate[委托异步] 由于需要不断的实例化 委托类 将会消耗cup 和 内存 3.Task [结合  async] 这种是三种中性能最好的  较低的cup和内存损耗 下面是例子: #region 委托异步 和  asycn 异步进行对比        /// <summary>        /// 运行        /// </summary>        /// <