异步编程

作者: dravenxiaokai | 来源:发表于2018-03-25 14:57 被阅读0次

AJAX中的回调函数

Ajax(Asynchronous JavaScript and XML)基于XMLHTTPRequest对象实现,在浏览器中使用AJAX

function ajax(url,callback){
  var xhr = new XMLHttpRequest(); //新建xhr对象
  xhr.onreadystatechange = function(){ //检测readystatechange事件
    if(xhr.readyState === XMLHttpRequest.DONE){ //当请求已经完成
      if(xhr.status = 200){ //如果服务器响应没有错误
        callback(null,xhr.responseText);
      }else{
        callback(xhr.status);
      }
    }
  }
  xhr.open("GET",url);//建议连接
  xhr.send(null);//发送body为空的数据
}

XMLHttpRequest在使用POST方式提交数据时,需要根据服务器端接口实现方式添加对应HTTP头。如果采用表单方式提交数据,则需要设置Content-Type,代码如下:

xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

使用先前创建的ajax函数异步请求数据:

ajax(url,function(err,data){
  if(err){
    console.log(err);
  }else{
    console.log('the response body is '+data);
  }
})

Promise模式

上述采用了callback方式实现异步编程,实际项目中层层嵌套容易造成回调地狱,如下:

ajax('http://apiA',function(dataA){
  ajax('http://apiB',function(dataB){
    ajax('http://apiC',function(dataC){
      //...
    });
  });
});

ES6提供了Promise对象,有效解决这一问题,采用Promise对象对之前定义的ajax函数进行包装:

function ajax(url){
  return new Promise(function(resolve,reject){
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
      if(xhr.readyState === XMLHttpRequest.DONE){
        if(xhr.status === 200){
          //成功时,结果采用resolve回调返回
          resolve(xhr.responseText);
        }else{
          //失败时,将出错信息采用reject回调返回
          reject(new Error('请求错误编码:'+xhr.status));
        }
      }
    };
    xhr.open("get",url);
    xhr.send(null);
  });
}

在调用异步操作时,直接使用Promise对象的实例方法执行成功和失败的操作:

ajax('/writer/dravenxiaokai').then(data=>{
  //data中包含返回的内容
}).catch(err=>{
  //err包含错误异步调用的错误信息
});

同时then方法支持多次链式调用

ajax('/author/dravenxiaokai').then(function(data){
  data.a = 'some value';
  return data;
}).then(function(data){
  //...
}).catch(function(err){
  //...
})

对于多重嵌套的异步调用,可以很方便的用过Promise实现,只需要在成功回调后,返回一个新的Promise对象即可,代码如下:

ajax('http://api1').then(function(data){
  return ajax('http://api2');//返回一个新的Promise对象
}).then(function(data){
  //data参数为api2返回的数据
})

生成器Generator

function* gen(){//定义一个生成器
  yield 1;//通过yield关键字,产出1
  yield 2;//通过yield关键字,产出2
  return 3;返回3
}
var g = gen();
g.next();//{value:1,done:false}
g.next();//{value:2,done:false}
g.next();//{value:3,done:true}
g.next();//{value:undefined,done:true}

在生成器中使用异步调用

function* demo(){
  var a = Promise.resolve(1);
  var b = Promise.resolve(a + 2);
  var c = Promise.resolve(b + 3);
  return c;
}
function co(generator){
  var gen = generator();
  function nextFunc(arg){
    var next = gen.next(arg);//首先执行以下next,取到第一个Promise
    if(!next.done){//如果生成器没有完成时,执行这个Promise
      next.value.then(function(data){
        console.log(data);
        nextFunc(data);
      });
    }else if(next.value){
      console.log(next.value);
    }
  };
  nextFunc();
}
co(demo);

关键字async & await

async function es7(){
  var a = await Promise.resolve(1);
  var b = await Promise.resolve(a * 2);
  var c = await Promise.resolve(b + 3);
  return c;
}
es7().then(function(data){//异步调用函数执行的结果是Promise对象
  console.log(data)
})

相关文章

  • ES6学习--异步编程--Generator

    异步编程 : (异步编程的语法目的就是让异步编程更像同步编程) 回调函数利用回调函数实现异步编程本身没有问题, 问...

  • JavaScript异步编程好文摘要

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

  • 认识异步编程

    认识异步编程 本章主要介绍异步编程的概念和作用,Java中异步编程的场景以及不同异步编程场景应使用什么技术实现。 ...

  • part1整理

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

  • 论异步编程

    相信本书介绍了CompletableFuture,大家就会认识到什么是异步编程。异步编程的好处。 异步编程最大好处...

  • 读书笔记#Java异步编程实战-上

    Java异步编程实战 chap1 认识异步编程 异步编程概念与作用在使用同步编程方式时,由于每个线程同时只能发起一...

  • Combine 基础知识

    摘自《SwiftUI和Combine编程》---《Combine异步编程》 响应式异步编程模型 将“状态变化”看作...

  • 关于node.js的那些事(四)—异步编程的优势与难点

    有异步I/O,必有异步编程。异步编程有它的优势,也有它的难点,下面我们就这门语言异步编程的优势和难点来展开谈...

  • 异步编程的前世今生

    异步编程的前世今生 1、为什么需要异步编程 异步编程是相对同步编程来说的,开发项目时,开发者总是希望,程序的执行顺...

  • 异步编程控制方法

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

网友评论

    本文标题:异步编程

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