如何在 JavaScript 中等待函数完成
目录
- JavaScript 中的 Sync 和 Async
- 在 JavaScript 中使用 回调 来等待一个函数的完成
- 在 JavaScript 中使用 promises 来等待一个函数的完成
- 使用 async/await 等待一个函数完成后再继续执行
本教程将介绍 JavaScript 的 回调、 承诺 和 Async/ await,并告诉你如何等待一个异步函数完成后再继续执行。
要了解什么是 Promises 和 Async/ await,我们首先要了解 JavaScript 中的 Sync 和 Async 函数是什么。
JavaScript 中的 Sync 和 Async
同步编程一次执行一条命令。当我们调用一个函数执行一个长期运行的动作时,它会停止程序,直到它完成。
JavaScript 是传统的单线程,即使是多核也是如此。我们可以让它只在一个叫做主线程的单线程上运行任务。
这样的同步行为是多线程的限制因素,但可以帮助用户编写代码而不用担心并发问题。
而在异步编程中,长期运行的动作会在主线程以外的另一个线程中执行,所以主线程的执行不会被阻塞。当该长期运行的函数完成后,主程序会被告知并获得访问结果。
JavaScript 中的大多数 I/O 基元都是非阻塞的。网络请求、文件系统操作都是非阻塞操作。被阻塞是 JavaScript 中的例外。
由于 JavaScript 是基于异步编程技术,所以有多种方法,如 回调、承诺 和 async/await,使你能够把你的函数按顺序执行。这样,一个代码块或一个函数不会在另一个特定函数完成之前被执行。
上图显示了两个函数异步和同步执行的明显变化。
在 JavaScript 中使用 回调 来等待一个函数的完成
如果我们有同步语句,那么执行这些语句之后就可以直接执行。
function one(){console.log("I am function One");
}
function Two(){console.log("I am function Two");
}one();
Two();
输出:
I am function One
I am function Two
假设我们要执行两个函数,functionOne() 和 functionTwo(),这样 functionOne() 应该在执行完 functionTwo() 里面的一些异步语句后执行。
function functionOne(_callback){// do some asynchronus work _callback();
}function functionTwo(){// do some asynchronus work functionOne(()=>{console.log("I am a callback");});
}functionTwo();
在执行上述代码时,最后在控制台中打印的是 I am a callback。著名的 callback 例子是 setTimeout 函数,在超时后要执行一个处理函数。
function testCallBack(){console.log("log before use setTimeout function");setTimeout(()=>{console.log("inside timeout");},5000);console.log("log after use setTimeout function");
}testCallBack();
输出:
log before use setTimeout function
log after use setTimeout function
inside timeout
在 JavaScript 中使用 promises 来等待一个函数的完成
promise 是一个代表异步操作的最终实现或失败的对象,我们用一个或多个 then 语句将实现回调附加到 promise 上。我们用一个或多个 then 语句将实现回调附加到 promise 上,并在 catch 中调用错误处理回调。
doFirstThing()
.then(result => doSecondThing(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => {console.log("The final result thing"+finalResult);
})
.catch(failureCallbackfunction);
}
像上面的例子一样把 then 和 catch 语句链起来,是承诺的优势之一。我们承诺一旦 doFirstThing() 被满足,就会 doSecondThing(result)。then 的参数是可选的,但如果你必须返回一个结果,则需要。
如果出现错误,浏览器会在链的最后寻找 catch 并执行。这和著名的 try-catch 非常相似。
下面的例子将帮助我们理解 promises 链,并告诉我们如何等待一个具有异步行为的函数完成执行后才能继续执行。
var resolvedFlag = true;let mypromise = function functionOne(testInput){console.log("Entered function");return new Promise((resolve ,reject)=>{setTimeout(()=>{console.log("Inside the promise");if(resolvedFlag==true){resolve("Resolved");}else{reject("Rejected")} } , 2000);});
};mypromise().then((res)=>{console.log(`The function recieved with value ${res}`)
}).catch((error)=>{console.log(`Handling error as we received ${error}`);
});
输出:
Entered function
Inside the promise
The function received with value Resolved
创建一个承诺可以像返回一个新的 Promise() 一样简单。Promise() 构造函数接收一个函数作为参数,它应该有两个参数-resolve 和 reject。
万一我们的事件实现了,需要返回结果,当成功完成我们正在做的事情时,我们使用 resolve() 函数。但如果发生了错误,需要处理,我们使用 reject() 将错误发送到 catch。
我们设置标志 resolvedFlag=true 来模拟 catch 中的错误处理。如果 resolvedFlag 设置为 false,则调用 reject() 函数,在 catch 块中处理错误。
输出:
Entered function
Inside the promise
Handling error as we received Rejected
使用 async/await 等待一个函数完成后再继续执行
在 JavaScript 的异步环境中,另一种等待函数执行后再继续执行的方法是使用 async/wait。
async 函数是由 async 关键字声明的函数,而在 async 函数内部只允许使用 await 关键字,用于暂停 async 函数内部的进度,直到实现或拒绝基于承诺的异步操作。
async 和 await 关键字以更简洁的风格实现了基于承诺的异步行为。
让我们来了解一下 async/await 是如何工作的。我们要等待的函数应该返回一个 Promise 类的实例,在调用它之前使用 await 关键字等待它执行。如上所述,包含 await 语句的函数必须与 async 语句一起声明。
下面的例子展示了如何等待那个基于承诺的函数完成后再继续执行。
function testAsync(){return new Promise((resolve,reject)=>{//here our function should be implemented setTimeout(()=>{console.log("Hello from inside the testAsync function");resolve();;} , 5000);});
}async function callerFun(){console.log("Caller");await testAsync();console.log("After waiting");
}callerFun();
输出:
Caller
Hello from inside the testAsync function
After waiting
如何在 JavaScript 中等待函数完成相关推荐
- html类型转换函数,如何在JavaScript中转换数据类型?
在JavaScript中,数据类型用于对一种特定类型的数据进行分类,确定可以分配给类型的值以及可以对其执行的操作.虽然由于类型强制,JavaScript会自动转换许多值,但为了达到预期的结果,通常最好 ...
- !! javascript_产量! 产量! 生成器如何在JavaScript中工作。
!! javascript by Ashay Mandwarya ?️?? 由Ashay Mandwarya提供吗? 产量! 产量! 生成器如何在JavaScript中工作. (Yield! Yiel ...
- regexp 好汉字符串_如何在JavaScript中使用RegExp确认字符串的结尾
regexp 好汉字符串 by Catherine Vassant (aka Codingk8) 由凯瑟琳·瓦森(Catherine Vassant)(又名Codingk8) 如何在JavaScrip ...
- 如何在JavaScript中实现堆栈和队列?
本文翻译自:How do you implement a Stack and a Queue in JavaScript? What is the best way to implement a St ...
- 如何在JavaScript中比较数组?
本文翻译自:How to compare arrays in JavaScript? I'd like to compare two arrays... ideally, efficiently. 我 ...
- 如何在javascript中使用多个分隔符分割字符串?
如何在JavaScript中使用多个分隔符拆分字符串? 我正在尝试在逗号和空格上进行拆分,但是AFAIK,JS的拆分功能仅支持一个分隔符. #1楼 对于那些想要在拆分功能中进行更多自定义的人,我编写了 ...
- 如何在JavaScript中验证电子邮件地址
如何在JavaScript中验证电子邮件地址? #1楼 与squirtle相比 ,这是一个复杂的解决方案,但是在正确验证电子邮件方面做得非常出色: function isEmail(email) { ...
- 如何在JavaScript中获取时间戳
如何在JavaScript中获取时间戳 +运算符 我们可以使用+运算符将日期对象直接转换为UNIX时间戳. 例如,我们可以这样写: +new Date() +日期对象之前操作者触发valueOf的方法 ...
- C#与Javascript变量、函数之间的相互调用2008年11月28日 星期五 05:28 P.M.1.如何在JavaScript访问C#函数?
C#与Javascript变量.函数之间的相互调用 2008年11月28日 星期五 05:28 P.M. 1.如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3 ...
最新文章
- 【Kotlin】扩展函数作用域分析 ( 扩展函数导入 | 扩展函数重载 | 扩展函数作用域优先级 )
- 【Laravel Cache】 配置redis 存储缓存,通俗易懂,一次就掌握
- 2条电信宽带 并线_理想更新“货车并线预警”遭用户吐槽 李想:目前功能偏保守 仍在优化...
- mysql 查询慢 分析_MySQL优化:定位慢查询的两种方法以及使用explain分析SQL
- 轻量社交APP系统ThinkSNS 简 权威发布 限时惠购
- 一问就打鼓,一用就糊涂,是我小看它了
- 2.24. Spring boot with Apache Kafka
- 实时仪表板的Postgres通知
- 常用Linux命令 mount df dd
- 定时让电脑进入休眠状态
- 如何使用DevStack在Ubuntu 18.04上安装OpenStack
- Illustrator 教程,如何在 Illustrator 中连接路径?
- WGS84地球坐标系,GCJ02火星坐标系,BD09百度坐标系简介与转换
- 2022电工(初级)操作证考试题库及模拟考试
- 免费好用的英语单词统计软件(带翻译功能)
- mac视频太大怎么压缩 苹果电脑怎么压缩视频大小的软件
- 【数据结构课程设计】基于商和余数的快速排序
- MySQL高级-(存储引擎、索引、锁)
- 【Linux】解压缩文件(一)
- K8s系列之:搭建高可用K8s v1.23.5集群详细步骤,3个master节点,3个Node节点