美文网首页前端开发
Javascript 异步编程

Javascript 异步编程

作者: vivaxy | 来源:发表于2017-01-31 12:48 被阅读26次

提到前端,与后端区别最大之处莫过于用于交互,交互中最需要开发人员额外关心的则是用户体验。如何保证在用户多个操作下,界面依然流畅?这里就要说到异步编程了。

Javascript 中的一大特性就是支持异步编程,异步编程能够让多个用户输入在后台同时执行,从而带来流畅的界面交互。但是开发人员却为此付出了沉重的代价。

Java 中默认一个线程中的代码就是同步的,通过另起线程或者进程,可以做到并行处理。而 Javascript 中只有一个线程,为了不让一个网络请求阻塞了用户操作,Javascript 天生就有同步和异步两种编程方式。

异步的实现方式是在调用第三方资源(网络请求)时,发起和回传被分成了两个指令,等到第三方资源有结果后,通过预先约定的一个事件或者回调函数等方式完成数据传递。

Javascript 中的异步通常有下面六种方式:

回调函数

这是最普遍的一种做法,是所有异步编程的本质,下面的其他方式只是外展现的编程模式不同。

回调函数句柄在发起请求时被传给了处理方,处理方在完成后进行调用。发起后程序就执行了后面的语句,等到处理方完成处理后才会执行回调中的语句。

var job1 = function(callback) {
    // do something
    callback();
};

var job2 = function() {
  
};

job1(job2);

回调函数不利于代码的阅读和维护,多个回调的嵌套会导致回调深渊。

job1(function() {
    job2(function() {
        job3(function() {
            job4(function() {
                // ...
            });
        });
    });
});

可以通过封装回调的方式或者下面提到的几种写法简化上面的语句的复杂度。

事件模式

var job1 = function() {
    // do something
    job1.emit('done');
};

var job2 = function() {
    
};

job1.on('done', job2);
job1();

事件模式降低了代码的耦合度,在复杂场景下会导致流程不清晰。

订阅者模式

var center = new Center();

var job1 = function() {
    // do something
    center.publish('job1 done')
};

var job2 = function() {
    
};

center.subscribe('job1 done', job2);
job1();

订阅者模式可以清晰地看到消息和订阅者。

Promise

var job1 = new Promise(function(resolve, reject) {
    // so something
    resolve();
});

var job2 = function() {
  
};

job1.then(job2);

多个回调的嵌套可以被写成:

job1.then(job2)
    .then(job3)
    .then(job4)
    // ...

Generator

ES6 规范中引入了生成器函数

let job1 = function*() {
    // do something
};

let job2 = function*() {

};

run(function*() {
    yield job1();
    yield job2();
});

可以用 co 来实现 generator 异步编程。

其中 yield 的函数也可以支持一个 Promise 对象。

async/await

const job1 = async() => {
    // do something
};

const job2 = async() => {
    
};

run(async() => {
    await job1();
    await job2();
});

其中 await 的对象可以是一个 Promise 对象。

最后的三种可以说都是以 Promise 为基础的。

对于异步方法,一旦开始执行了,怎么中断呢?下面列举三种方法:

原生异步支持的中断

var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
xhr.abort(); // cancel

标记方式

添加一个变量,通过变量值确定是否执行下面的回调。这种方式并不能中断异步函数的执行,但是能控制接下去依赖的方法的执行。

var flag = true;
job1(function() {
    if (flag) {
        job2();
    }
});

Promise.race

await Promise.race([timeoutPromise(timeout), job1]);
await job2;

timeoutPromise 抛出异常,阻止 job2 的执行。

异步编程的异常处理又应该怎么处理呢?

分回调

job1({
    success: function() {
      
    },
    error: function() {
      
    }
});

分参数

job1(function(err, data) {
    if (err) {
        // error
    } else {
        // success
    }
});

抛出异常

Javascript 中一个线程有异常抛出会阻止了下面的所有语句的执行。

try {
    await job1();
    // success
} catch (ex) {
    // error
}

参考资料

相关文章

  • JavaScript异步编程好文摘要

    JavaScript之异步编程简述JavaScript异步编程

  • part1整理

    函数式编程:JavaScript函数式编程指南 异步编程:异步编程 Promise源码 JavaScript基础知...

  • 一篇看完JS异步编程的进阶史

    一、Javascript实现异步编程的过程以及原理 1、为什么要用Javascript异步编程 众所周知,Java...

  • ES6 之 Promise

    Promise是JavaScript异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步...

  • JavaScript(ES6) - Async

    异步编程对JavaScript语言太重要。Javascript语言的执行环境是“单线程”的,如果没有异步编程,根本...

  • 异步编程控制方法

    javascript 具有的一个特性就是异步编程。异步编程具有的优势本文不做细说,本文主要是总结如何异步编程中出现...

  • Javascript------异步编程的4种方法

    Javascript异步编程的4种方法

  • 深入了解下Promise

    Promise 意义 Promise 的诞生与 Javascript 中异步编程息息相关,js 中异步编程主要指 ...

  • JavaScript学习笔记(5) 异步-- Promise

    写在前面 异步编程对Javascript语言非常重要,在Javascript的发展道路上,异步编程的方法也是一直在...

  • AJAX入门

    AJAX(Async Javascript and Xml):在AJAX中的异步不是异步编程中的异步,而是泛指“局...

网友评论

    本文标题:Javascript 异步编程

    本文链接:https://www.haomeiwen.com/subject/zfqkittx.html