zoukankan      html  css  js  c++  java
  • Promise和async和await的理解

    1.回调函数直接作为函数参数

    1.1传统的方式,使用jquery的get方法

    语法

    $.get(URL,data,function(data,status,xhr),dataType)

    该方法里面可以设置回调函数,如下代码,可以在console窗口中直接执行,function(data)就代表get调用/数据请求之后的回调函数

    $.get('/')
    //{readyState: 1, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
    
    $.get('/',function(data){console.log(data.length)})
    //{readyState: 1, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
    //208896
    
    $.get('/',function(data2){console.log(data2.length)})
    //{readyState: 1, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
    //206281
    
    $.get('/',function(){console.log("a")})
    //{readyState: 1, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
    //a
    

    1.2 fetch方法

    请注意,fetch 规范与 jQuery.ajax() 主要有三种方式的不同:

    • 当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject, 即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。
    • fetch() 不会接受跨域 cookies;你也不能使用 fetch() 建立起跨域会话。其他网站的 Set-Cookie 头部字段将会被无视。
    • fetch 不会发送 cookies。除非你使用了credentials初始化选项。(自 2017 年 8 月 25 日以后,默认的 credentials 政策变更为 same-origin。Firefox 也在 61.0b13 版本中进行了修改)
    fetch('./')
    //Promise {<pending>}
    
    $.get('/',function(data){console.log(data.length)})
    //{readyState: 1, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
    //208896
    
    fetch('./').then(res=>res.text()).then(data=>console.log(data.length))
    //Promise {<pending>}
    //206267
    

    1.1 的jquery是将回调函数作为一个参数传递,而fetch里面是利用promise的then方法来调用回调函数。

    1.3 Promise方法

    setTimeout(console.log(123),1000)
    //123
    
    new Promise((resolve,reject)=>{
            setTimeout(function(){resolve(123)},1000)
        }).then(res=>console.log(res))
    //Promise {<pending>}
    //间隔1s后,123
    
    
    new Promise((resolve,reject)=>{
            setTimeout(function(){reject(123)},1000)
        }).then(res=>console.log(res))
    //Promise {<pending>}
    //Uncaught (in promise) 123
    
    
       new Promise((resolve,reject)=>{
            setTimeout(function(){reject(123)},1000)
        }).then(res=>console.log(res))
        .catch(e=>console.log(e))
    //Promise {<pending>}
    //123
    

    new Promise的时候里面内容会立即执行!!因而为了能实现调用时执行,Promise一般都是作为函数的返回值,可以将普通的回调函数作为参数的形式改造成promise的形式,和执行如果setTimeout的效果是一样的。promise返回的是reject,就会抛异常,一般reject的通过catch来捕获异常。

    接下来定义一个函数p1,该函数返回Promise对象,执行该函数就会返回一个Promise对象。

    var p1=()=>new Promise((resolve,reject)=>{
            setTimeout(function(){resolve(12345)},1000)
        })
    
    p1
    //()=>new Promise((resolve,reject)=>{
    //        setTimeout(function(){resolve(12345)},1000)
     //   })
    
    p1()
    //Promise {<pending>}
    

    await会拿到resolve结果,是then函数的语法糖,如下代码,async+await是promise+then的语法糖。

    async function q1(){
        var res=await p1();
        console.log(res);
    }
    q1()
    //12345
    
    function q1(){
        p1().then(res=>console.log(res));
    }
    q1()
    //12345
    

    思考一下下面的代码,最后会同时打印出12345。

    var p1=()=>new Promise((resolve,reject)=>{
            setTimeout(function(){resolve(12345)},1000)
        })
    
    async function q2(){
        var res=await p1();
        console.log(res);
    }
    
    async function q1(){
        var res=await p1();
        console.log(res);
    }
    
    q1();
    q2();
    //Promise {<pending>}
    //12345
    //12345
    

    2.async和await的理解

    async函数(异步函数)

    函数的返回值为promise对象

    promise对象的结果由aync函数的返回值决定。

    await表达式

    await操作符用于等待一个Promise对象。他只能在async function中使用

    await得到的结果就是Promise成功的value

    async function fn() {
        return 1;
    }
    const result = fn();
    console.log(result);
    
    async function fn1() {
        throw 2;
    }
    const result1 = fn1();
    console.log(result1);
    
    

    代码运行结果为,可以看出async函数的结果值为Promise对象

    Promise {: 1}

    1. proto__: Promise

    2. [[PromiseStatus]]*: "resolved"

    3. [[PromiseValue]]*: 1

    4. Promise {: 2}

      1. proto: Promise
      2. [[PromiseStatus]]: "rejected"
      3. [[PromiseValue]]: 2

    从代码运行结果可以看出,async函数的返回值是Promise对象,拿到这个对象之后我们就可以调用then函数了,调用这个then的回调函数,

    async function fn1() {
        throw 2;
    }
    const result1 = fn1();
    console.log(result1);
    result1.then(
        value => {
            console.log("onResolved()", value);
        },
        reason => {
            console.log("onRejected()", reason)
        }
    )
    

    代码运行结果为:

    Promise {<rejected>: 2}
    index.js:19706 onRejected() 2
    

    async函数的返回其实是这样的

    async function fn1() {
         return Promise.resolve(2);
        // return Promise.reject(3);
    }
    

    上面的代码可以发现async函数的返回结果是Promise对象,这个Promise对象的结果必须通过调用then函数才能取出来。如果我们不想通过调用then函数来处理得到value值呢?

    这里注意一点await在的函数一定要声明为async函数,不然会报错,如下代码,fs()函数如果没有被定义为async函数,则会报错,这样我们直接通过await就拿到了async函数返回的值。

    async function fn2() {
        return 1;
    }
    
    async function f3() {
        const value=await fn2();
        console.log(value);
    }
    f3();
    

    如果await右侧表达式不是promise,得到的结果就是它本身。

    async function f4() {
        const value=await 11;
        console.log(value);
    }
    f4();
    //11
    

    上面的例子await得到的都是成功的结果,如果想得到失败的结果呢??用try catch来进行,如下代码

    async function fn2() {
        return Promise.reject('ed');
    }
    async function f4() {
        try {
            const value = await fn2();
        } catch (error) {
            console.log(error);
        }
    }
    
    f4();
    //ed
    
  • 相关阅读:
    来自风湿病研究院RA患者队列研究显示, RA日常诊治时特别是早期RA患者成功维持新ACR/EULAR缓解标准能获
    系列超声发现脊柱关节炎附着点处新骨形成
    超声(PDUS)能否容易检出侵蚀?比较PDUS与microCT对正常人群和RA患者小关节生理和皮质断裂的评价
    根据ACR/EULAR 2010 标准定义RA放射学侵蚀病变
    比较依那西普和柳氮磺胺吡碇治疗早期中轴脊柱关节炎1年后的停药缓解率和缓解时间-ESTHER试验的2年数据
    Matlab Computer Vision and Pattern Recognition toolbox
    vi/vim 命令手册(初级篇)
    GCC设定include和库路径(转载)
    linux 下查找文件或者内容常有命令
    svn命令在linux下的使用
  • 原文地址:https://www.cnblogs.com/zdjBlog/p/12588319.html
Copyright © 2011-2022 走看看