js中异步函数async function变同步函数的简单入门

 更新时间:2023年04月24日 10:17:32   作者:321茄子  
这篇文章主要介绍了js中异步函数async function变同步函数的简单入门,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

js异步函数async function变同步函数入门

js 中异步函数之所以特别,一个重要的原因就是它执行完成的时间、耗费的时间靠人的主观是不得而知的。

所以不能靠设置定时函数来让上一个程式完成之后来进行下一个函数。

接上次的文章:js 异步获取到的数据 到底能不能 赋值给一个全局变量

所以 promise 就突出了它的作用,目前程式执行在那个阶段 结果是什么 promise 知道。新建一个 promise 对象。

new Promise(function (resolve, reject) {
    // 要做的事情...
});

尝试一个 ajix 请求

<script>
    var goodsInfo = {};
    $(document).ready(function(){
    //    使用Promise
    new Promise(function (resolve,reject) {
            $.ajax({url:"https://api-hmugo- web.itheima.net/api/public/v1/home/catitems",success:function(result){
                    goodsInfo = result;
                    resolve(goodsInfo);
                    console.log(goodsInfo);
                }});
        }).then(function () {
            console.log(goodsInfo);
        })
        console.log(1);
        console.log(goodsInfo);
    });
</script>

看是不是在 .then() 中得到了经过ajax请赋值后的全局变量 goodsInfo 的值,如果再有什么对 goodsInfo 的操作,在 .then 中进行即可。

ajax在项目会频繁使用,将其封装成一个函数会更方便

<script>
 
    var goodsInfo = {};
    $(document).ready(function(){
 
// 封装一个 promise 函数,在promiise对象前面多加了一个return
        function promiseFun (url){
            return new Promise(function (resolve,reject) {
                $.ajax({url:url,success:function(result){
                        goodsInfo = result;
                        resolve(goodsInfo);
                        console.log(goodsInfo);
                    }});
            })
        }
// 调用函数
        promiseFun("https://api-hmugo-web.itheima.net/api/public/v1/home/catitems").then(function () {
            console.log(goodsInfo);
        })
        console.log(1);
        console.log(goodsInfo);
    });
</script>

结果依然一样。调用的时候是不是又简约一点。 async function 感觉是又进了异步

// 定义规则
async function asyncFunc() {
    // await 后面必须是定义过的 promise function 
    await myfunction();
    await youfunction();
    await shefunction();
    somefunction();
    xxxxxx;
    
}
asyncFunc();
<script>
    var goodsInfo = {};
    var data ={};
    $(document).ready(function(){
// 先定义一个 promise function
        function promiseFun (url){
            return new Promise(function (resolve,reject) {
                $.ajax({url:url,success:function(result){
                        goodsInfo = result;
                        resolve(goodsInfo);
                        console.log(goodsInfo);
                    }});
            })
        }
// 在定义一个 asyns function 
     async function asyncFuunc(){
// 看这里面的代码执行顺序是不是跟同步函数简直一模一样
            await promiseFun("https://api-hmugo-web.itheima.net/api/public/v1/home/catitems");
            console.log(goodsInfo);
            data=goodsInfo;
            console.log(data)
            console.log(2);
     }
// 调用 asyns 函数
        asyncFuunc();
        console.log(1);
        console.log(goodsInfo);
    });
</script>

异步函数(async/await)

异步函数

异步函数,也称为"async/await" (语法关键字),是ES6 期约模式在ECMAScript 函数中的应用。async/await 是ES8 规范新增的。为了解决利用异步结构组织代码的问题。

  • async

async 关键字用于声明异步函数。这个关键字可以用在函数声明、函数表达式、箭头函数和方法上:

    async function foo() {}   
    let bar = async function() {};  
    let baz = async() => {};   
    class Qux {   
        async qux() {}   
    }

异步函数如果使用return 返回了值(没有return 则会返回undefined),这个值会被Promise.resolve() 包装成一个期约对象。

    async function foo(){
        console.log(1)
    }

    console.log(foo()); //promise {<fulfilled>:undefined}
    foo().then(console.log) //undefined
    console.log(2)
    //1
    //2
    //undefined
  • await

await 关键字可以暂停异步函数代码的执行,等待期约解决。await 会暂停执行异步函数后面的代码,让出JS 运行时的执行线程。这个行为与生成器函数中的yield 关键字是一样的。await 关键字同样是尝试 “解包” 对象的值,然后将这个值传给表达式,再异步恢复异步函数的执行。

await 关键字必须在异步函数中使用;异步函数的特质不会扩展到嵌套函数。否则会抛出SyntaxError;

async function foo(){
    await Promise.resolve(3);
}
foo();

async/await 中真正起作用的是await。异步函数如果不包含await 关键字,其执行基本上跟普通函数没什么区别。

JavaScript 运行时在碰到await 关键字时,会记录在哪里暂停执行。等到await 右边的值可用了,js运行时会向消息队列中推送一个任务,这个任务会恢复异步函数的执行。

因此,即使await 后面跟着一个立即可用的值,函数的其他部分也会被异步求值。

    async function foo() { 
        console.log(2);   
        await null;
        console.log(4);  
    }   
    console.log(1);
    foo();
    console.log(3);
    // 1
    // 2
    // 3
    // 4
    
    控制台中输出结果的顺序很好地解释了运行时的工作过程:
    (1)打印1;
    (2)调用异步函数foo();
    (3)(在foo()中)打印2;
    (4)(在foo()中)await关键字暂停执行,为立即可用的值null向消息队列中添加一个任务;
    (5)foo()退出;
    (6)打印3;
    (7)同步线程的代码执行完毕;
    (8)JavaScript运行时从消息队列中取出任务,恢复异步函数执行;
    (9)(在foo()中)恢复执行,await取得null值(这里并没有使用);
    (10)(在foo()中)打印4;
    (11)foo()返回。

异步函数策略

  • 实现sleep()

很多人在刚开始学习JavaScript时,想找到一个类似Java中Thread.sleep()之类的函数,好在程序中加入非阻塞的暂停。以前,这个需求基本上都通过setTimeout()利用JavaScript运行时的行为来实现的。

有了异步函数之后,就不一样了。一个简单的箭头函数就可以实现sleep():

 async function sleep(delay) {
        return new Promise((resolve) => setTimeout(resolve, delay));
    }

    async function sleepfoo(){
        const t0 = Date.now();
        await sleep(2000);
        const t1 = Date.now();
        console.log(t1 - t0);
    }
    sleepfoo()
    //2002  任务队列执行,时间不一定
  • 利用平行执行
  • 串行执行期约
  • 栈追踪与内存管理

注意:

异步函数是将期约应用于JavaScript函数的结果。异步函数可以暂停执行,而不阻塞主线程。无论是编写基于期约的代码,还是组织串行或平行执行的异步代码,使用异步函数都非常得心应手。异步函数可以说是现代JavaScript工具箱中最重要的工具之一。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 谈一谈js中的执行环境及作用域

    谈一谈js中的执行环境及作用域

    这篇文章主要和大家一起谈一谈js中的执行环境及作用域,本文依据面试过程中遇到的问题进行探讨,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • JS返回上一页实例代码通过图片和按钮分别实现

    JS返回上一页实例代码通过图片和按钮分别实现

    返回上一页的方法有很多,本代码通过图片和按钮分别实现,感兴趣的朋友可以参考下,希望对大家有所帮助
    2013-08-08
  • 在JavaScript中模拟类(class)及类的继承关系

    在JavaScript中模拟类(class)及类的继承关系

    众所周知,JavaScript中没有类,然而我们却可以动手实现一个拥有继承特性的类,所以接下来我们要讨论的便是在JavaScript中模拟类(class)及类的继承关系:
    2016-05-05
  • 全解跨域请求问题处理方法及分析

    全解跨域请求问题处理方法及分析

    这篇文章主要为大家介绍了全解跨域请求问题处理方法及分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2023-07-07
  • JavaScript中的return布尔值的用法和原理解析

    JavaScript中的return布尔值的用法和原理解析

    这篇文章主要介绍了JavaScript中的return布尔值的用法和原理解析,需要的朋友可以参考下
    2017-08-08
  • 纯javascript实现图片延时加载方法

    纯javascript实现图片延时加载方法

    看到一篇博客说土豆网的图片是延迟加载的。原理是这样:页面可见区域以下的图片先不加载,等到用户向下滚动到图片位置时,再进行加载。这样做的好处是当页面有好几屏内容时,这样我们就可以只加载用户需要看的图片,减少服务器向用户浏览器发送图片文件所产生的负荷。
    2015-08-08
  • javascript添加前置0(补零)的几种方法

    javascript添加前置0(补零)的几种方法

    很多时候为了显示格式,需要在某一字符串不满位的情况下进行前补0操作。下面这篇文章就给大家主要介绍了javascript添加前置0(补零)的几种方法,文中给出了详细的示例代码,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-01-01
  • js HTML5多图片上传及预览实例解析(不含前端的文件分割)

    js HTML5多图片上传及预览实例解析(不含前端的文件分割)

    这篇文章主要详细解析了js HTML5多图片上传及预览实例,不含前端的文件分割,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • JS判断浏览器类型与操作系统的方法分析

    JS判断浏览器类型与操作系统的方法分析

    这篇文章主要介绍了JS判断浏览器类型与操作系统的方法,结合实例形式分析了JS针对各种常见浏览器与操作系统进行判断的方法,需要的朋友可以参考下
    2020-04-04
  • JavaScript模拟实现键盘打字效果

    JavaScript模拟实现键盘打字效果

    这篇文章主要介绍了JavaScript模拟实现键盘打字效果,本文直接给出实例代码,需要的朋友可以参考下
    2015-06-06

最新评论