suchen

Heim  >  Fragen und Antworten  >  Hauptteil

javascript - Was bedeutet es, asynchron und synchron zu schreiben?

Ist Synchronisation nicht einfach Synchronisation und ist Asynchron nicht einfach Asynchron? Was bedeutet es, asynchron und synchron zu schreiben?

天蓬老师天蓬老师2736 Tage vor1141

Antworte allen(4)Ich werde antworten

  • 扔个三星炸死你

    扔个三星炸死你2017-07-05 10:54:36

    异步调用对于当前线程来说,是非阻碍的,所以要想知道异步处理是否完成,或者是否出错,通常都是通过事件或回调来实现的,这在 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 消除了回调,所以看起来跟写非异步(即同步)代码一样。

    参考:

    • 闲谈异步调用“扁平”化

    • 从地狱到天堂,Node 回调向 async/await 转变

    • 理解 JavaScript 的 async/await

    Antwort
    0
  • PHP中文网

    PHP中文网2017-07-05 10:54:36

    异步时常见回调函数嵌套,形如:

    // 先读取 a
    fs.readFile('a.txt', (a) => {
      // a 读取成功后读取 b
      fs.readFile('b.txt', (b) => {
        // b 读取成功后读取 c
        fs.readFile('c.txt'. (c) => {
          console.log(a + b + c)
        })
      })
    })

    这时出现了回调嵌套,需要一层一层往里套,非常容易出错且不好维护。

    同步方式写异步类似于:

    function * asyncWrapper () {
      const a = yield read('a.txt')
      const b = yield read('b.txt')
      const c = yield read('c.txt')
      console.log(a + b + c)
    }
    // 使用形如 co 的库自动执行异步逻辑
    co(asyncWrapper)

    这时候异步业务逻辑就通过正常的同步方式实现了。

    Antwort
    0
  • 我想大声告诉你

    我想大声告诉你2017-07-05 10:54:36

    同步方式写异步指得是代码的组织形式而已。使用async/await可以实现同步方式写异步,看下面代码:

    const testAsync = async () => {
      const t = await f();
      console.log(t);
    };
    
    testAsync();

    f是一个异步操作,如果不使用async/await,直接同步的方式打印t,结果肯定是undefined;使用async/await之后,代码看上去形式还是同步的,但是里面是先执行异步操作f,再打印t的

    Antwort
    0
  • 伊谢尔伦

    伊谢尔伦2017-07-05 10:54:36

    楼上两个答案足矣

    Antwort
    0
  • StornierenAntwort