异步处理

为什么会有异步操作

在Javascript中很多方法使用的是异步处理,例如:

const response = axios.get("https://xxxx.com")

上面的代码是一个网络请求的操作,这个操作是一个异步操作,也就是说其运行不影响主程序的运行

这时候就会有一个问题,我希望先执行异步操作的代码,然后再执行主程序剩余的代码如何实现?譬如如下的操作:

function httpRequest(){
  const response = axios.get("https://xxxx.com");
  return response;
}

如果不考虑异步的问题,这个函数的返回值为可能空,因为axios.get()这个还没有执行完就返回response(没有被赋值)了

各种用法

Promise

Promise是一个对象类型,其性质和int, double类似,代表异步操作的结果,使用mdn web docs的原话是这么说的:

Promise 对象表示异步操作最终的完成(或失败)以及其结果值。

那怎么样才叫一个Promise呢?

Promise是一个对象,它可以这样用简单的对象方法创建:

new Promise(()=>{
  // ...
});

完整的用法是这样的:

new Promise((resolve, reject)=>{
  // 一般情况下执行内容...
}).catch((err)=>{
  // 出错的话...
}).finally(()=>{
  // 最后执行...
})

这其中有几个参数:

下面的await 和async会在后续内容继续介绍

  • resolve 表示结果需要返回的值,一般这么使用:

    async function test(){
        const value=await new Promise((resolve)=>{
            resolve("Hello world!");
        });
        console.log(value);
    }
    test();
    // 输出: 
    // Hello world
    
  • reject 表示会抛出一个错误原因,可以这么使用:

    async function test(){
        await new Promise((resolve,reject)=>{
            // resolve("Hello world!");
            reject("我故意的")
        }).catch((err)=>{
            console.log("错误原因: "+err);
        })
    }
    
    test();
    // 输出: 
    // 错误原因: 我故意的
    

then

表示在Promise之后需要执行什么,注意需要有resolve值才能执行

async function test() {
    new Promise((resolve, reject) => {
        console.log("Hello 1");
    }).then(() => {
		    // 没有resolve值,所以这里不会被执行
        console.log("Hello 2");
    })
}

test();
// 输出: 
// Hello 1

可以在then后面添加参数用于接收resolve的值:

async function test() {
    new Promise((resolve, reject) => {
        console.log("Hello 1");
        resolve("Resolved!");
    }).then((value) => {
        console.log(value);
        console.log("Hello 2");
    })
}

test();
// 输出:
/*
Hello 1
Resolved!
Hello2
*/

async和await

Promise和一般代码一起使用的时候,往往需要这样的操作:

我需要等待xxx操作完成再执行下面的!

这个操作对应的就是await

await不能单独使用,需要与async配合使用,async需要添加在函数上,例如下面的:

async function httpRequest(){
  // ...
  await // ...
}

但是注意,await后面需要接的是一个Promise实例在先前的例子中, axios.get()就是一个Promise`实例。

但是注意,大多数情况下JavaScript的代码都是顺序执行的,所以非异步处理的代码强行加上awaitasync会报错或者无意义。

以下的操作都是错误的

async function test(){
  await var a = "Hello world";
  console.log(a);
}

// 错误,await后面需要有表达式,并且无意义
function plus(a,b){
  return a+b;
}
async function test(){
  var a = await plus(1,1);
  console.log(a);
}

// 无意义await和async

来看看正解:

async function httpRequest(){
  const response = await axios.get("https://xxxx.com");
  return response;
}