javascript - 同步方式写异步到底指什么?

查看:157
本文介绍了javascript - 同步方式写异步到底指什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

同步不就是同步,异步不就是异步吗?同步方式写异步到底指什么?

解决方案

异步调用对于当前线程来说,是非阻碍的,所以要想知道异步处理是否完成,或者是否出错,通常都是通过事件或回调来实现的,这在 Node.js 比比皆是。Ajax 就是很典型的异步调用,以 jQuery.ajax 为例

$.getJSON("http://api.youapp.com/resouce1")
    .done(function(jo) {
        console.log("api resouce1 返回的是", jo);
    });

jQuery 的 Ajax 返回的是 jQuery 的 Promise 对象,一般习惯上我们会使用 done() 回调来处理调用完成之后的事情。但实际它也有标准 Promise 的 then(),所以上面的 done 是可以改成 then 的,但是要注意,done 是以事件的形式注册回调,它返回当前这个 Promise 对象本身,可以链式调用注册若干个回调。而 then 返回的是另一个 Promise 对象(标准 Promise 规范),链式调用的话,每次调用并非作用在同一个 Promise 对象上。

如果在一个回调中需要进行另一个异步调用,就需要在回调中注册另一个回调。比如要获取某个数据,需要先从 api1 获取某个值,再用这个值去 api2 获取某个资源,再用这个资源中的某个值去 api3 获取这个值,这样的回调写出来会像这样:

$.getJSON("http://api.youapp.com/resouce1")
    .then(function(jo) {
        $.getJSON("http://api.youapp.com/resouce2?id=" + jo.blaId)
            .then(function(jo2) {
                $.getJSON("http://api.youapp.com/resouce3?xxx=" + jo2.xxxValue)
                    .then(function(value) {
                        console.log("总算拿到了", value);
                    });
            });
    });

这才三层……很可怕的形式。这种形式被称为回调地狱。

大家想了很多办法来解决这种问题,Promise 就是其一,但是 Promise 仍然不能完全摆脱这种形式。co 库也是解决方案之一,同样不能完美摆脱。

不过 ES2017 引入了 async/await,也就是所谓的以同步的形式写异步,比如上面那段代码可以改写成


async function xxx() {
    const jo = await $.getJSON("http://api.youapp.com/resouce1");
    const jo2 = await $.getJSON("http://api.youapp.com/resouce2?id=" + jo.blaId);
    const value = await $.getJSON("http://api.youapp.com/resouce3?xxx=" + jo2.xxxValue);
    console.log("总算拿到了", value);
}

async/await 消除了回调,所以看起来跟写非异步(即同步)代码一样。

参考:

这篇关于javascript - 同步方式写异步到底指什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆