Javascript异步的发展与6种解决方案总结

本文详细介绍了JavaScript异步编程的发展,包括事件循环的概念,以及回调、Promise、Generator和async/await四种解决方案。重点讲解了Promise和async/await的使用,包括它们的状态、方法和优缺点。最后总结了async/await作为Generator的改进,如何解决了回调地狱问题,以及其潜在的性能影响。
摘要由CSDN通过智能技术生成

异步(Asynchronous)指同一时间不止一个事件发生,或者说是多个相关事件不等待前一事件完成就发生。异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其它线程将处理完成,并回调通知此线程。

现在与将来

一个完整的javascript程序,几乎一定是由多个块构成的。这些块中只有一个是现在执行,其余的则会在将来执行。最常见的块单位是函数。

举个例子

function now() {
   
 return 21;
}
function later() {
   
 answer = answer * 2;
 console.log( "Meaning of life:", answer );
}
var answer = now();
setTimeout( later, 1000 );

上面的例子两个块:现在执行的部分,以及将来执行的部分

现在执行部分

function now() {
   
 return 21;
}
function later() {
    .. }
var answer = now();
setTimeout( later, 1000 );

将来执行部分

answer = answer * 2;
console.log( "Meaning of life:", answer );

任何时候,只要把一段代码包装成一个函数,并指定它在响应某个事件(定时器、鼠标点击、Ajax响应等)时执行,你就是在代码中创建了一个将来执行的块,也由此在这个程序中引入了异步机制。程序中现在运行的部分和将来运行的部分之间的关系就是异步编程的核心。

事件循环

异步与事件循环密切相关,在了解解决方案前,建议先看下并发模型与事件循环。

异步编程解决方案

  • 回调
  • 事件监听
  • 发布订阅
  • Promise
  • Generator
  • async/await

注意:Promise、Generator、async/await 在IE浏览器都不支持,需要做兼容处理。

下面介绍常用的解决方案。

1.回调

JavaScript 语言对异步编程的实现,就是回调函数。所谓回调函数,就是把任务的第二段单独写在一个函数里面,等到重新执行这个任务的时候,就直接调用这个函数。

缺点:大量的嵌套回调会造成回调地狱,难以维护。

// 如果下一请求依赖上一个请求的返回值,就需要不断嵌套
$.ajax({
    
  url: "url-1", 
  success: function(){
   
    $.ajax({
    
      url: "url-2", 
      success: function(){
   
        $.ajax({
    
          url: "url-3", 
          success: function(){
   
            // ...
          }
        });
      }
    });
  }
});
2.promise(ES6)
介绍
  • promise是一个代表了异步操作最终完成或者失败的对象。
  • 本质上,promise是一个函数返回的对象, 它可以绑定回调函数
  • Promise对象是一个构造函数,用来生成Promise实例。
  • 使用promise最直接的好处就是能够使用then进行链式调用
创建

Promise 对象是由关键字 new 及其构造函数来创建的。

var p = new Promise((resolve, reject) => {
   
    // 一系列异步操作
    // resolve()
    // reject()
});
console.log(p) // Promise

想要某个函数拥有 promise 功能,只需让其返回一个promise即可。

function myAsyncFunction(url) {
   
    return new Promise((resolve, reject) => {
   
        const xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.onload = () => resolve(xhr.responseText);
        xhr.onerror = () => reject(xhr.statusText);
        xhr.send();
    });
  };
状态

一个 Promise有以下几种状态:

  • pending: 初始状态,既不是成功,也不是失败状态。
  • fulfilled: 意味着操作成功完成。状态:pengding=>fulfilled
  • rejected: 意味着操作失败。状态:pending=>rejected

一个 promise 对象处在 fulfilled 或 rejected 状态而不是 pending 状态,那么它也可以被称为 settled 状态。你可能也会听到一个术语 resolved ,它表示 promise 对象处于 settled状态。但是在平时大家都习惯将 resolved 特指 fulfilled 状态

var p1 = new Promise((resolve, reject) => {
   
});
console.log(p1); // pending

var p2 = new Promise((resolve, reject) => {
   
    resolve('成功');
});
console.log(p2); // fulfilled

var p3 = new Promise((resolve, reject) => {
   
    reject('失败');
});
console.log(p3); // reject

注意:promise状态是不可逆的

promise的状态 只有从pengding =》fulfilled 或者 pending =》 rejected,而不会反过来。并且已经resolve的数据,后面无论如何修改,都不会改变then中接受到的数据。

new Promise((resolve, reject) => {
   
    var num = 100;
    resolve(num);
    num = 999;
    resolve(num); // resolve 也不会改变已传出去的num 100
    console.log(num) // 999
}).then(result => {
    
    console.log(result) // 100
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ronghua_yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值