异步那些事

简介: ajax,axios,回调地狱,Generator,promise,async/awiat

异步请求

JS中ajax原生请求

var xhr;
xhr=new XMLHttpRequest();
open('GET','url地址')
xhr.onreadyStateChange=function(){
  if(xhr.readyState==4&&xhe.status==200){
    console.log(xhr.responseText);
  }
};
send();

封装后的ajax请求

GET

$.ajax({
  type:'get',//不写默认get
  url:'index.php'
  data:{
     name:'jim',
     age:10
   }//data中的数据也可以当作参数写在url后面
  success:function(data){
    console.log(data)
   }
})

POST

$.ajax({
  type:'post',
  url:'',
  data:{
    name:'jim',
    age:10
  },
  success:function(info){
    console.log(info)
  }
})

Vue中的axios请求

  • Vue没有任何ajax请求方法
  • 在vue1时代大家都用一个插件vue resource来发请求

    • 支持promise
  • 在Vue2.0时代,大家都用第三方库axios

    • 支持promise
  • 后来在HTML5时代,浏览器增加了一个特殊的异步请求,fetch,只在移动端使用
  • 结合声明钩子获取数据

安装

npm install axios

引入

import axios from 'axios'

执行GET请求

// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  }) //then promise语法,下面有具体描述
  .catch(function (error) {
    console.log(error);
  });

// 可选地,上面的请求可以这样做
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });//catch 捕捉错误对象

POST请求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

执行多个并发请求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }));

可以通过axios传递相关配置来创建请求

axios(config)

//发送post请求
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

axios(url[, config])

// 发送 GET 请求(默认的方法)
axios('/user/12345');

异步操作

回调地狱

**以同时读取文件为例,因为是异步请求无法保证顺序,快慢取决于读取的文件大小.

无法保证顺序的代码*

var fs = require('fs')

fs.readFile('./data/a.txt', 'utf8', function (err, data) {
  if (err) {
    // return console.log('读取失败')
    // 抛出异常
    //    1. 阻止程序的执行
    //    2. 把错误消息打印到控制台
    throw err
  }
  console.log(data)
})

fs.readFile('./data/b.txt', 'utf8', function (err, data) {
  if (err) {
    // return console.log('读取失败')
    // 抛出异常
    //    1. 阻止程序的执行
    //    2. 把错误消息打印到控制台
    throw err
  }
  console.log(data)
})

fs.readFile('./data/c.txt', 'utf8', function (err, data) {
  if (err) {
    // return console.log('读取失败')
    // 抛出异常
    //    1. 阻止程序的执行
    //    2. 把错误消息打印到控制台
    throw err
  }
  console.log(data)
})

通过回调嵌套的方式保证顺序

var fs = require('fs')

fs.readFile('./data/a.txt', 'utf8', function (err, data) {
  if (err) {
    // return console.log('读取失败')
    // 抛出异常
    //    1. 阻止程序的执行
    //    2. 把错误消息打印到控制台
    throw err
  }
  console.log(data)
  fs.readFile('./data/b.txt', 'utf8', function (err, data) {
    if (err) {
      // return console.log('读取失败')
      // 抛出异常
      //    1. 阻止程序的执行
      //    2. 把错误消息打印到控制台
      throw err
    }
    console.log(data)
    fs.readFile('./data/c.txt', 'utf8', function (err, data) {
      if (err) {
        // return console.log('读取失败')
        // 抛出异常
        //    1. 阻止程序的执行
        //    2. 把错误消息打印到控制台
        throw err
      }
      console.log(data)
    })
  })
})
  • 但是这样不停的嵌套很不好重复代码太多,反复的嵌套,最后形成回调地狱
  • 所以在 EcmaScript 6 中新增了一个 API:Promise。

Promise 基本语法

var fs = require('fs')

// 在 EcmaScript 6 中新增了一个 API Promise
// Promise 是一个构造函数

// 创建 Promise 容器
// Promise 容器一旦创建,就开始执行里面的代码
var p1 = new Promise(function (resolve, reject) {
  fs.readFile('./data/aa.txt', 'utf8', function (err, data) {
    if (err) {
      // 失败了,承诺容器中的任务失败了
      // console.log(err)
      // 把容器的 Pending 状态变为 Rejected

      // 调用 reject 就相当于调用了 then 方法的第二个参数函数
      reject(err)
    } else {
      // 承诺容器中的任务成功了
      // console.log(data)
      // 把容器的 Pending 状态改为成功 Resolved
      // 也就是说这里调用的 resolve 方法实际上就是 then 方法传递的那个 function
      resolve(data)
    }
  })
})

// p1 就是那个承若
// 当 p1 成功了 然后(then) 做指定的操作
// then 方法接收的 function 就是容器中的 resolve 函数
p1
  .then(function (data) {
    console.log(data)
  }, function (err) {
    console.log('读取文件失败了', err)
  })

综合以上封装刚才的readFile文件

var fs = require('fs')

function pReadFile(filePath) {
  return new Promise(function (resolve, reject) {
    fs.readFile(filePath, 'utf8', function (err, data) {
      if (err) {
        reject(err)
      } else {
        resolve(data)
      }
    })
  })
}

pReadFile('./data/a.txt')
  .then(function (data) {
    console.log(data)
    return pReadFile('./data/b.txt')
  })
  .then(function (data) {
    console.log(data)
    return pReadFile('./data/c.txt')
  })
  .then(function (data) {
    console.log(data)
  })

Generator函数的概念

Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)

function *gen(x){
  var y=yied x+2;
  return y;
}
  • 上面的代码就是Generator函数,他是可以暂停的,所以函数名之前要加*加以区别;
  • 整个Generator函数就是一个封装的异步任务,或者说是异步任务的容器,异步操作需要暂停的地方,都用yield语句注明.执行方法如下:

    var g=gen(1);
    g.next()//{value:3,done:fasle}
    g.next()//{value:undefined,done:true}

  • 上面代码中,调用 Generator 函数,会返回一个内部指针(即遍历器 )g 。这是 Generator 函数不同于普通函数的另一个地方,即执行它不会返回结果,返回的是指针对象。调用指针 g 的 next 方法,会移动内部指针(即执行异步任务的第一段),指向第一个遇到的 yield 语句,上例是执行到 x + 2 为止。
  • 换言之,next 方法的作用是分阶段执行 Generator 函数。每次调用 next 方法,会返回一个对象,表示当前阶段的信息( value 属性和 done 属性)。value 属性是 yield 语句后面表达式的值,表示当前阶段的值;done 属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。

Async/Awiat 配合promise使用

阅读本文前,期待您对上面promise以及ES6有所了解,会更容易理解。

本文以体验为主,不会深入说明.

第一个例子

  • Async/Await应该是目前最简单的异步方案了
  • 这里我们要实现一个暂停功能,输入N毫秒,则停顿N毫秒后才继续往下执行。

    var sleep = function (time) {

    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve();
        }, time);
    })

    };

    var start = async function () {

    // 在这里使用起来就像同步代码那样直观
    console.log('start');
    await sleep(3000);
    console.log('end');

    };

    start();

控制台先输出start,稍等3秒后,输出了end。

基本规则

  1. async 表示这是一个async函数,await只能用在这个函数里面。
  2. await 表示在这里等待promise返回结果了,再继续执行。
  3. await 后面跟着的应该是一个promise对象(当然,其他返回值也没关系,只是会立即执行,不过那样就没有意义了…)

获得返回值

  • await等待的虽然是promise对象,但不必写.then(..),直接可以得到返回值。

    var sleep = function (time) {

    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            // 返回 ‘ok’
            resolve('ok');
        }, time);
    })

    };

    var start = async function () {

    let result = await sleep(3000);
    console.log(result); // 收到 ‘ok’

    };


捕捉错误

  • 既然.then(..)不用写了,那么.catch(..)也不用写,可以直接用标准的try catch语法捕捉错误。

    var sleep = function (time) {

    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            // 模拟出错了,返回 ‘error’
            reject('error');
        }, time);
    })

    };

    var start = async function () {

    try {
        console.log('start');
        await sleep(3000); // 这里得到了一个返回错误
        
        // 所以以下代码不会被执行了
        console.log('end');
    } catch (err) {
        console.log(err); // 这里捕捉到错误 `error`
    }

    };

补充try catch

  • try 语句允许我们定义在执行时进行错误测试的代码块。
  • catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
  • JavaScript 语句 try 和 catch 是成对出现的。

    try
      {
      //在这里运行代码
      }
    catch(err)
      {
      //在这里处理错误
      }
    

在这里我们故意在try中写错一个字,catch会捕捉到try中的错误,并执行代码处理它;

<!DOCTYPE html>
<html>
<head>
<script>
var txt="";
function message()
{
try
  {
  adddlert("Welcome guest!");
  }
catch(err)
  {
  txt="There was an error on this page.\n\n";
  txt+="Error description: " + err.message + "\n\n";
  txt+="Click OK to continue.\n\n";
  alert(txt);
  }
}
</script>
</head>

<body>
<input type="button" value="View message" onclick="message()">
</body>

</html>

弹出窗为:

本页有一个错误.
错误描述:adddlert is not defined
点击确定继续

总的来说就是try里面放要运行的代码,catch里面放处理错误的代码;

补充throw

  • 抛出异常
  • 错误可以自定义

三者混合用:

<!DOCTYPE html>
<html>
<body>

<script>
function myFunction()
{

try
{ 
var x=document.getElementById("demo").value;
if(x=="")    throw "值为空";
if(isNaN(x)) throw "不是数字";
if(x>10)     throw "太大";
if(x<5)      throw "太小";
}

catch(err)
{
var y=document.getElementById("mess");
y.innerHTML="错误:" + err + "。";
}
}

</script>

<h1>我的第一个 JavaScript 程序</h1>
<p>请输入 5 到 10 之间的数字:</p>
<input id="demo" type="text">
<button type="button" onclick="myFunction()">测试输入值</button>
<p id="mess"></p>

</body>
</html>

以上就是自己总结的,如有错误欢迎指出,时间太紧,没有太详细.主要还是当作自己的随笔笔记,总结为主.哈哈哈~

相关文章
|
9天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
5天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
4135 13
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
|
7天前
|
人工智能 JavaScript 应用服务中间件
零门槛部署本地AI助手:Windows系统Moltbot(Clawdbot)保姆级教程
Moltbot(原Clawdbot)是一款功能全面的智能体AI助手,不仅能通过聊天互动响应需求,还具备“动手”和“跑腿”能力——“手”可读写本地文件、执行代码、操控命令行,“脚”能联网搜索、访问网页并分析内容,“大脑”则可接入Qwen、OpenAI等云端API,或利用本地GPU运行模型。本教程专为Windows系统用户打造,从环境搭建到问题排查,详细拆解全流程,即使无技术基础也能顺利部署本地AI助理。
6821 14
|
5天前
|
存储 人工智能 机器人
OpenClaw是什么?阿里云OpenClaw(原Clawdbot/Moltbot)一键部署官方教程参考
OpenClaw是什么?OpenClaw(原Clawdbot/Moltbot)是一款实用的个人AI助理,能够24小时响应指令并执行任务,如处理文件、查询信息、自动化协同等。阿里云推出的OpenClaw一键部署方案,简化了复杂配置流程,用户无需专业技术储备,即可快速在轻量应用服务器上启用该服务,打造专属AI助理。本文将详细拆解部署全流程、进阶功能配置及常见问题解决方案,确保不改变原意且无营销表述。
4396 5
|
4天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
3198 8
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
7天前
|
人工智能 JavaScript API
零门槛部署本地 AI 助手:Clawdbot/Meltbot 部署深度保姆级教程
Clawdbot(Moltbot)是一款智能体AI助手,具备“手”(读写文件、执行代码)、“脚”(联网搜索、分析网页)和“脑”(接入Qwen/OpenAI等API或本地GPU模型)。本指南详解Windows下从Node.js环境搭建、一键安装到Token配置的全流程,助你快速部署本地AI助理。(239字)
4479 21
|
13天前
|
人工智能 API 开发者
Claude Code 国内保姆级使用指南:实测 GLM-4.7 与 Claude Opus 4.5 全方案解
Claude Code是Anthropic推出的编程AI代理工具。2026年国内开发者可通过配置`ANTHROPIC_BASE_URL`实现本地化接入:①极速平替——用Qwen Code v0.5.0或GLM-4.7,毫秒响应,适合日常编码;②满血原版——经灵芽API中转调用Claude Opus 4.5,胜任复杂架构与深度推理。
8151 12
|
3天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
2154 4