迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 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 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Do you understand JavaScript closures?

发布时间:2025/02/21 浏览次数:108 分类:JavaScript

The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.

Do you know about the hidden traps in variables in JavaScript?

发布时间:2025/02/21 浏览次数:178 分类:JavaScript

Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av

How much do you know about the Prototype Chain?

发布时间:2025/02/21 浏览次数:150 分类:JavaScript

The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start

用 jQuery 检查复选框是否被选中

发布时间:2024/03/24 浏览次数:102 分类:JavaScript

在本教程中学习 jQuery 检查复选框是否被选中的所有很酷的方法。我们展示了使用直接 DOM 操作、提取 JavaScript 属性的 jQuery 方法以及使用 jQuery 选择器的不同方法。你还将找到许多有用的

扫一扫阅读全部技术教程

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

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便