迹忆客 专注技术分享

当前位置:主页 > 学无止境 > WEB前端 > JavaScript >

如何在 JavaScript 中等待函数完成

作者:迹忆客 最近更新:2023/03/10 浏览次数:

本教程将介绍 JavaScript 的 回调承诺Async/await,并告诉你如何等待一个异步函数完成后再继续执行。

要了解什么是 PromisesAsync/await,我们首先要了解 JavaScript 中的 SyncAsync 函数是什么。

同步编程一次执行一条命令。当我们调用一个函数执行一个长期运行的动作时,它会停止程序,直到它完成。

JavaScript 是传统的单线程,即使是多核也是如此。我们可以让它只在一个叫做主线程的单线程上运行任务。

这样的同步行为是多线程的限制因素,但可以帮助用户编写代码而不用担心并发问题。

而在异步编程中,长期运行的动作会在主线程以外的另一个线程中执行,所以主线程的执行不会被阻塞。当该长期运行的函数完成后,主程序会被告知并获得访问结果。

JavaScript 中的大多数 I/O 基元都是非阻塞的。网络请求、文件系统操作都是非阻塞操作。被阻塞是 JavaScript 中的例外。

由于 JavaScript 是基于异步编程技术,所以有多种方法,如 回调承诺async/await,使你能够把你的函数按顺序执行。这样,一个代码块或一个函数不会在另一个特定函数完成之前被执行。

sync and async

上图显示了两个函数异步和同步执行的明显变化。

如果我们有同步语句,那么执行这些语句之后就可以直接执行。

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

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);
}

像上面的例子一样把 thencatch 语句链起来,是承诺的优势之一。我们承诺一旦 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() 构造函数接收一个函数作为参数,它应该有两个参数-resolvereject

万一我们的事件实现了,需要返回结果,当成功完成我们正在做的事情时,我们使用 resolve() 函数。但如果发生了错误,需要处理,我们使用 reject() 将错误发送到 catch

我们设置标志 resolvedFlag = true 来模拟 catch 中的错误处理。如果 resolvedFlag 设置为 false,则调用 reject() 函数,在 catch 块中处理错误。

输出:

Entered function
Inside the promise
Handling error as we received Rejected

在 JavaScript 的异步环境中,另一种等待函数执行后再继续执行的方法是使用 async/wait

async 函数是由 async 关键字声明的函数,而在 async 函数内部只允许使用 await 关键字,用于暂停 async 函数内部的进度,直到实现或拒绝基于承诺的异步操作。

asyncawait 关键字以更简洁的风格实现了基于承诺的异步行为。

让我们来了解一下 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

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 Angular 中上传文件

发布时间:2023/04/14 浏览次数:71 分类:Angular

本教程演示了如何在 Angular 中上传任何文件。我们还将介绍如何在文件上传时显示进度条,并在上传完成时显示文件上传完成消息。

Angular 2 中的复选框双向数据绑定

发布时间:2023/04/14 浏览次数:139 分类:Angular

本教程演示了如何一键标记两个复选框。这篇有 Angular 的文章将着眼于执行复选框双向数据绑定的不同方法。

在 AngularJs 中加载 spinner

发布时间:2023/04/14 浏览次数:107 分类:Angular

我们将介绍如何在请求加载时添加加载 spinner,并在 AngularJs 中加载数据时停止加载器。

在 Angular 中显示和隐藏

发布时间:2023/04/14 浏览次数:78 分类:Angular

本教程演示了 Angular 中的显示和隐藏。在开发商业应用程序时,我们需要根据用户角色或条件隐藏一些数据。我们必须根据该应用程序中的条件显示相同的数据。

在 Angular 中下载文件

发布时间:2023/04/14 浏览次数:104 分类:Angular

本教程演示了如何在 angular 中下载文件。我们将介绍如何通过单击按钮在 Angular 中下载文件并显示一个示例。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便