async / await 的执行时间

本文详细解释了JavaScript中async和await的功能与作用时机,包括async如何使函数返回Promise对象,await如何暂停和恢复异步执行流程,以及它们如何影响函数执行顺序。

目录

一、async 是做什么的,什么时候工作?

二、await 是做什么的?

三、async/await 对函数执行顺序的影响。

四、 写在最后


JavaScript 异步编程的终极方案 async / await。

一、async 是做什么的,什么时候工作?

1. async 让函数返回一个 promise 对象。会把函数的返回值通过 promise.resolve() 封装成一个 promise 对象,如果函数没有返回值,通过 promise.resolve(undefined) 封装返回一个 promise 对象。

async function fn() {
    return 'foobar';
}
console.log(fn()); // Promise {<resolved>: "foobar"}

函数没有返回值时:

async function fn() {
    console.log('foobar');
}
console.log(fn()); // Promise {<resolved>: undefined}

2. async 声明的也是一个函数,因此函数的执行也是在手动调用该函数的时候。

二、await 是做什么的?

1. await 后面接表达式,可以是 promise 对象,也可以不是。

2. await 返回值

如果后面接的是 promise 对象,则返回该对象的结果(resolve 或是 reject 的参数);如果等待的不是promise 对象,就返回其本身。

3.await 必须用在 async 函数内部。

三、async/await 对函数执行顺序的影响。

总的执行顺序:当 async 函数执行到 await 时,会将 await 后面接的函数先执行一遍,然后跳出整个 async 函数,继续执行当前事件循环,当前事件循环结束之后,回到 async 函数中,如果这时 await 函数已经有了结果,那么就继续执行 async 函数,否则继续等待。如果 await 函数返回一个 promise 对象,此时把该对象添加到 microtasks 队列。

看下面的例子:

function commonFunc() {
    console.log('commonFunc start...');
    return 'commonFunc end';
}
async function fn1() {
    console.log('fn1 start...');
    return 'fn1 end';
}
async function fn2() {
    console.log('fn2 start...');
    let res1 = await commonFunc();
    console.log(res1);
    let res2 = await fn1();
    console.log(res2);
}
fn2();
let promise = new Promise(resolve => {
    console.log('promise start...');
    resolve('this is a promise');
});
promise.then(value => console.log(value));

最终的输出顺序为

fn2 start...
commonFunc start...
promise start...
commonFunc end
fn1 start...
this is a promise
fn1 end

结合代码我们来具体分析 

/* 注意 commonFunc 是一个普通函数 */
function commonFunc() {
    console.log('commonFunc start...');
    return 'commonFunc end';
}
/* fn1 是一个 async 函数,将被处理为一个 promise 对象*/
async function fn1() {
    console.log('fn1 start...');
    return 'fn1 end';
}
async function fn2() {
    console.log('fn2 start...'); // ① 第一个输出
    let res1 = await commonFunc();  // ② fn2 顺序执行到这里,先把 await 后面的函数执行一遍
                                    // 因此第二个输出了 commonFunc 里面的 'commonFunc start...'
                                    // 然后会第一次跳出整个 fn2,继续执行后面的task。
    console.log(res1);  // ④ task 执行完毕之后,回到 fn2
                        // commonFunc 只是一个普通的函数,将返回值赋值给 res1 后输出。
    let res2 = await fn1(); // ⑤ 同样,先执行一遍 fn1 ,输出 'fn1 start...'
                            // 由于 fn1 是一个 promise 对象,因此此时把 这个 promise 推到 micro tasks 队列中。
                            // 第二次跳出fn2.
    console.log(res2);  // ⑦ 执行完 micro tasks 队列首位的 promise 后,再次回到 fn2
                        // 此时 fn1 已经等待结束,输出 'fn1 end'
}
fn2(); // 这里执行了 fn2, 所以 'fn2 start...'第一个被输出
let promise = new Promise(resolve => {
    console.log('promise start...'); // ③ 第一次跳出 fn2 后,先执行到这里,所以第三个输出
                                     // 将这个 promise 推到 micro tasks 队列的首位
    resolve('this is a promise');
});
promise.then(value => console.log(value));  // ⑥ 第二次跳出 fn2 之后,task 已经执行完毕,开始执行 micro tasks 队列。
                                            // 由于这个 promise 位于 micro tasks 的首位,因此第6个输出。

四、 写在最后

如果能够把上面的例子完全弄明白,可能需要了解 task 与 micro tasks,参照https://www.cnblogs.com/QH-Jimmy/p/6493389.html。之所以不使用 setTimeout来模拟耗时事件,是因为 setTimeout 的回调函数会创建另一个 task,肯定会最后执行,就不是在一个事件轮询中了。

 

内容概要:本文提出了一种基于改进扩散模型的高海拔地区新能源高波动出力场景生成方法,并提供了完整的Python代码实现。该方法针对高海拔地区风能、光伏等新能源出力波动剧烈、不确定性高的特点,通过优化扩散模型的结构与训练策略,有效捕捉历史据的概率分布特征与时序相关性,从而生成高质量、多样化的出力场景。文中详细阐述了模型的学推导、网络架构设计、损失函优化及采样算法改进,并通过实验证明其在拟合精度、场景多样性与稳定性方面优于传统生成模型,为电力系统在高比例新能源接入下的规划、调度与风险评估提供了可靠的场景输入支持。; 适合人群:具备一定Python编程能力和机器学习基础,从事新能源发电预测、电力系统分析、智能优化、场景生成等方向研究的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①用于高海拔地区风电、光伏出力的不确定性建模与多场景生成;②支撑含高渗透率新能源的电力系统随机优化调度、鲁棒决策与风险评估;③为相关学术研究、论文复现与算法改进提供可运行的技术方案与代码基础; 阅读建议:建议读者结合所提供的完整资源(代码、据集、说明文档)进行实践操作,重点关注扩散模型的前向加噪与反向去噪过程的设计细节,以及如何将其适配于新能源时序据的生成任务,通过参调优与对比实验深入理解模型的生成机制与性能边界。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值