在项目开发中难免会遇到异步的问题,最原始的做法就是函数嵌套,但是这样难免会造成函数的地狱回调,于是我们可使用异步来解决这些问题。


那么什么是异步呢?

所谓"异步",简单说就是一个任务不是连续完成的,可以理解成该任务被人为分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段。

比如,有一个任务是读取文件进行处理,任务的第一段是向操作系统发出请求,要求读取文件。然后,程序执行其他任务,等到操作系统返回文件,再接着执行任务的第二段(处理文件)。这种不连续的执行,就叫做异步。

相应地,连续的执行就叫做同步。由于是连续执行,不能插入其他任务,所以操作系统从硬盘读取文件的这段时间,程序只能干等着。


一.简单介绍:


1.Promise:

概念:

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

特点:

Promise有三种状态,分别是:

  1. pending(进行中);
  2. fulfilled(已成功);
  3. rejected(已失败)

基本语法:

const promise = new Promise(function(resolve, reject) {
  // ...
  if (/* 成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

2.Generator

概念:

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。

Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。

执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

特点:

形式上,Generator 函数是一个普通函数,但是有两个特征。

  1. function关键字与函数名之间有一个星号;
  2. 函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。

基本语法:

function* first_generator() {
  yield '1';
  yield '2';
  return '3';
}

var fg = first_generator();

3.async

概念:

ES2017 标准引入了 async 函数,使得异步操作变得更加方便。

async 函数是什么?它就是 Generator 函数的语法糖。

async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。

基本语法:

// 函数声明
async function foo() {}

// 函数表达式
const foo = async function () {};

// 对象的方法
let obj = { async foo() {} };
obj.foo().then(...)


// 箭头函数
const foo = async () => {};

二.基本使用

1.原始写法:

在函数进行嵌套的时候,会形成如下代码:

function add() {
     fn(...){
		fn(...){...}
	}    
}

在上一个完成后接着执行下一个,少量还好万一处理事件一多,代码维护性就会变差,逻辑就会看起来很乱。

2.Promise:

var a = 10,b=20
const promise = new Promise((resolve,reject)=>{
	if (/* 异步操作成功 */){
    	resolve(value);
  	} else {
    	reject(error);
    }
})

promise.then((res)=>{
   .....
}).then((res1)=>{
   ....
})

相对于原始写法来说确实思维很清晰,也方便我们的维护。

3.Generator:

function * gen(){
    yield '123'
    yield '234'
    yield '456'
}

var _g=gen()

console.log(_g.next().value);
console.log(_g.next().value);
console.log(_g.next().value);

注意:虽然_g.next().value写法一样,但是执行的结果不一样,如下图所示:
在这里插入图片描述

4.async:

const async_a = async function () {
    const f1 = await console.log(123);;
    const f2 = await console.log(234);;
};

async_a()

async返回 Promise 对象,正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

async function f() {
    // 等同于
    // return 123;
    return await 123;
}
  
f().then(v => console.log(v))

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐