【JavaScript】 异步

一、异步的概念

参考资料:JavaScript 异步编程

同步 Synchronous (sync):按代码顺序执行
异步 Asynchronous (async) :不按代码顺序执行

  • 从主线程发射一个子线程来完成任务
  • 子线程一旦发射了以后就会与主线程失去同步
  • 无法确定它的结束,无法将它合并到主线程中去的。
  • JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理。
回调函数

Node.js 回调函数

例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件 I/O 操作。

回调函数一般作为函数的最后一个参数出现:
function fun1( ... , fun2(...){...} ) {...}

二、异步的使用

1. setTimeout(cb, ms)

setTimeout()全局函数执行后,产生一个子线程在规定毫秒之后执行回调函数,且只执行一次,返回一个代表定时器的句柄值。

setTimeout(function () {
    console.log("1");
}, 3000);
console.log("2");

在这里插入图片描述

2. Promise

参考资料:
JavaScript Promise
异步函数Async(es2017)

① 概念
Promise 是一个 ECMAScript 6 提供的,目的是更加优雅地书写复杂的异步任务。

② 状态
Promise 对象代表一个异步操作,有三种状态:

  • pending(进行中)
  • resolved(已完成,又称 Fulfilled)
  • rejected(已失败)

执行回调里的 resolve(); 这个 promise 就被标记为 resolverd

③ 构造函数/起始函数
new Promise(function(resolve, reject){...})
Promise 构造函数只有一个参数,是一个函数,这个函数在构造之后会直接被异步运行,所以我们称之为起始函数。起始函数包含两个参数 resolve 和 reject 都是函数:

  • resolve() 代表一切正常。
  • reject() 是出现异常时所调用的。

throw "Some error"; 或者 reject("Some error")
resolve 和 reject 的作用域只有起始函数,不包括 then 以及其他序列
resolve 和 reject 并不能够使起始函数停止运行,别忘了 return。

//例子
new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log("First");
        resolve();
    }, 1000);
})

④ 方法
Promise 类有三个方法,这三个方法的参数都是函数,

  • .then() 可以将参数中的函数添加到当前 Promise 的正常执行序列,传入的函数会按顺序依次执行,有任何异常都会直接跳到 catch 序列
  • .catch() 则是设定 Promise 的异常处理序列,
  • .finally() 是在 Promise 执行的最后一定会执行的序列。

resolve() 中可以放置一个参数向下一个 then 传递一个值
then 中的函数返回一个值,该值传递给下一个 then。
then 中的函数返回一个 Promise 对象,那么下一个 then 将相当于对这个返回的 Promise 进行操作。

1.异步函数执行的结果总是一个promise,这个promise在异步函数开始执行的时候被创建。
2.然后函数体被执行,执行可能会通过return或throw永久完成,或者通过await临时完成(这种情况,之后会继续执行)。
3.promise被返回。

当执行异步函数体的时候,return x将会resolve(x),throw err将会reject(err),promise的完成是异步的。换句话说,then(),catch()中的回调函数总是在当前代码完成之后执行。

异步的方法函数最后一个参数为回调函数
回调函数的第一个参数包含了错误信息(error)

3. async 异步函数

参考资料:
ES6 async 函数
async/await 异步函数
异步函数Async(es2017)

async function name([param[, param[, ... param]]]) { statements }

  • 函数声明:async function
  • 参数:
    • name: 函数名称。
    • param: 要传递给函数的参数的名称。
    • statements: 函数体语句。
  • 返回值:async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。

[return_value] = await expression;

  • await 操作符只能在异步函数 async function 内部使用
  • 参数:expression:一个 Promise 对象或者任何要等待的值。
  • 返回值:返回 Promise 对象的处理结果。
    • 如果等待的不是 Promise 对象,则返回该值本身。
    • 如果等待的是 Promise 对象,await 将等待 Promise 正常处理完成并返回其处理结果
4. util.callbackify()

参考资料:
util 实用工具 官网
Node.js 常用工具

util 模块中
util.callbackify(original)
将 async 异步函数(或者一个返回值为 Promise 的函数)转换成遵循异常优先的回调风格的函数

  • 参数:original 为 async 异步函数。
  • 返回值:返回传统回调函数(或者一个返回值为 Promise 的函数)
    • 在返回的回调函数中,第一个参数为拒绝的原因(如果 Promise 解决,则为 null),第二个参数则是解决的值。
//例子
const util = require('util');

async function fn() {
  return 'hello world';
}
const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {
  if (err) throw err;
  console.log(ret);
});

//结果
hello world
5. fs 系统

参考资料:Node.js 文件系统
fs 模块中有许多函数采用异步方式:如
fs.open(path, flags[, mode], callback) 在异步模式下打开文件
fs.stat(path, callback) 通过异步模式获取文件信息
fs.writeFile(file, data[, options], callback) 异步模式下写入文件
fs.read(fd, buffer, offset, length, position, callback) 异步模式下读取文件,该方法使用了文件描述符来读取文件。
fs.close(fd, callback) 异步模式下关闭文件,该方法使用了文件描述符来读取文件。
fs.ftruncate(fd, len, callback) 异步模式下截取文件,该方法使用了文件描述符来读取文件。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript中,异步导出是指在导出模块时,使用异步操作获取数据,并将其作为导出的结果。引用中的示例代码展示了一个问题:当我们尝试在JS中使用export导出异步的数据时,会发现输出的是异步前的结果。这是因为在export.js文件中,我们使用setTimeout函数来模拟异步操作,在2秒后改变asyData的值。然而,由于export语句是在异步操作之前执行的,导致导出的是异步前的结果,即[1,2,3]。 为了解决这个问题,我们可以使用Promise对象来实现异步导出。引用中的示例代码展示了如何导出一个Promise对象。在export.js文件中,我们创建了一个Promise,使用setTimeout函数模拟异步操作,并在操作完成后使用resolve方法将更新后的asyData作为结果传递给Promise。然后,我们使用export语句将Promise对象Pm导出。在import.js文件中,我们通过import语句引入Pm,并使用then方法来处理Promise的结果。当Promise对象的异步操作完成后,then方法会执行回调函数,我们可以在回调函数中获取到更新后的结果[3,2,1]。 总而言之,JavaScript异步导出可以通过使用Promise对象来实现,在export时将异步操作的结果传递给Promise,并在import时使用then方法获取异步结果。这样可以确保导出的数据是异步操作后的最新结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [ES6模块化export异步导出数据](https://blog.csdn.net/weixin_44765930/article/details/110004014)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [space-agency:在 JavaScript 中处理异步任务组的示例](https://download.csdn.net/download/weixin_42143092/20445696)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值