js任务队列

JS & 事件循环机制、调用栈、堆、主线程、宏任务队列、微任务队列、缓存管理之间的关系 JS 事件循环、异步任务的概念。 阅读详情

setTimeout和任务对列的联系,单线程优点,性能优化;

一、诡异的SETTIMEOUT

setTimeout(code, ms)函数是指在指定的毫秒数(ms)后调用函数或执行代码块,并返回一个整数,后续可以通过clearTimeout(num)传递这个整数来取消该定时器。

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

一个很普通的setTimeout定时器,运行上面的代码输出的结果是2、1,但是明明定时器是:在0ms也就是“立即”执行log(1),然后再log(2)啊,结果顺序却是反的,甚至在log(2)之前加上一个耗时的处理也不会影响这个输出结果:

var startTime = +new Date();
setTimeout(function(){
    console.log(1);
}, 0);
while((+new Date() - startTime) < (1000 * 3)){
    // console.log('...');
}
console.log(2)

以上加了一个3秒的while循环阻塞进程,按正常理解log(2)需要在log(1)后3秒才会输出,但输出结果还是跟之前一样,下面逐步分析这种情况的原因。

二、任务队列

JavaScript是单线程的语言,在执行时必须等前面的任务处理完以后才会处理后面的;而且是一个一个连续同步执行的,不象多线程可以同时处理多个任务。JavaScript中的任务分为同步任务和异步任务,同步任务就是主线程上一个个排队执行的任务;相反的异步任务则不进入主线任务而是被加入到“任务队列”中,任务队列的任务只有在主线任务执行完成之后才去处理任务队列中的任务。

这样就可以解释上面的问题了:setTimeout(function(){console.log(1);}, 0);这里的0代表的是0秒后加入到任务队列并没有执行,他要等主线程上面的任务console.log(2)执行完成后才会执行。

setTimeout、setInterval和回调这两种形式的程序会添加到任务队列,示例如下:

function foo(){
    console.log(1);
}
function bar(){
    console.log(2);
}
foo();
bar();
$('#btn').on('click', function(){
    console.log(3);
});
setTimeout(function(){
    console.log(4);
}, 0);

主线程上的任务就是执行foo()、bar()和后面的事件绑定和设定定时器,而任务队列中有一个事件回调任务和一个定时器任务,主线程foo()、bar()执行结束后,就会询问任务队列是否有任务,然后“全部执行”。所以setTimeout(code, ms)表示的是ms后把code任务添加到队列,而不是说ms后就会执行,就算setTimeout时间设置成0,他也要等主线程上的任务完成才会执行,所以setTimeout的执行时间并不是准确的,往往真正执行的时间要比你设定的时间偏大。

JavaScript事件循环与任务队列 阅读详情

相关推荐

JavaScript 任务队列详解:Event Loop、宏任务与微任务

Event Loop 执行顺序执行同步代码(主线程上的任务)。执行所有微任务(Microtask Queue)。执行一个宏任务(Macrotask Queue)。回到步骤 2,执行所有新的微任务。继续执行宏任务队列中的下一个任务。优先级对比微任务 > 宏任务(微任务会在每个宏任务前全部执行完)。多个微任务会按照添加顺序执行。多个宏任务也是按照添加顺序执行。掌握事件循环(Event Loop)

一萧烟雨任平生 2033

如何在 JavaScript 中实现任务队列

使用javascript实现任务队列

it_czh的博客 1122

UE5实战:如何用Georeference插件搞定百度地图坐标转换(附完整代码)

本文详细解析了在UE5中使用Georeference插件实现百度地图坐标转换的全流程,包括BD-09到UE内部坐标的转换算法、UTM投影配置及性能优化技巧。通过完整代码示例和实战案例,帮助开发者高效解决数字孪生项目中的地理坐标转换难题。

weixin_30955617的博客 94

js实现任务(promise任务)队列

任务队列 队列的特点就是先进先出 先开始的任务执行完后,才能开始执行后续任务 另外任务队列中有任务时是自动执行的。 另外提一点,实现稍微复杂一点功能,全都是闭包!! 设计:new一个队列,返回值是一个function,这个function的入参为为task(类型promise),返回值也是promise const queue = new Queue(); queue(task1).then(data=>console.log(data)); queue(task2).then(data=&gt

XIAOLONGJUANFENG的博客 4433

Simulink/Requirements Toolbox 学习(一):概述

编写、导入、导出需求并使需求正式化;两种创建需求的模块:需求编辑器、需求透视;描述需求的方式:文本、图像和关键字;通过导入和导出需求文件,与第三方需求管理工具(例如 Microsoft Word、Microsoft Excel®、IBM DOORS和 IBM DOORS Next)集成。涉及模块:Requirements Eidtor、Requirements Table等;

855

COMSOL电磁仿真案例——感应线圈

COMSOL电磁建模仿真案例——感应线圈

冲击10w 6万+

JS任务队列

JS任务队列首先进行读取,将同步代码压入执行栈中进行执行,当有异步任务时,提交给对应的异步进程进行处理(异步API) 异步API处理完成之后,再推入到任务队列之中,任务队列又分为宏任务和微任务,通过队列的方式分别把任务压入宏任务队列或者微任务队列,在主线程执行完毕之后,查询微任务队列,微任务队列执行完毕之后,取出第一个宏任务进行执行,再看宏任务中是否有微任务,如果有就执行微任务,没有就执行下一个宏任务。

m0_55686063的博客 1041

火山引擎之火山方舟知识库+OpenWebUI,搭建独属于自己的AI智能客服

创建接入点,接入点名称可按个人需求而定,比如Doubao-1.5-pro-32k,在添加模型选择Doubao-1.5-pro-32k,点击确定(PS:有些模型不支持知识库,若发现后续无法选择,请重新创建推理接入点。选择应用广场,创建零代码应用,在创建好的应用设置内编辑相关信息,并选择推理接入点,即先前建好的推理接入点;此处的模型名称是火山的模型ID名称,可在OpenWebUI设置-模型 中修改名称。至此所需的apikey和模型ID和请求的api地址(可选配置,非本文重点参数)。进入火山官网,注册账号。

AmaZInGvCH的博客 2652

JS 任务队列与事件循环

任务队列与事件循环笔记

weixin_57911482的博客 1800

LPDDR5 学习笔记02:上电初始化与下电时序

LPDDR5上电初始化流程需严格遵守时序要求:首先确保电源按顺序上电(VDD1→VDD2H→VDD2L→VDDQ),RESET_n保持低电平至电压稳定。初始化包含自动ZQ校准、命令总线训练(CBT)、WCK2CK电平校准和DQ总线训练四个关键阶段,需完成全部训练后才能正常操作。在双电源轨系统中,须在CBT前设置MR13寄存器。复位操作需保持RESET_n低电平至少tPW_RESET时间,断电时要求CS保持低电平且电源电压有序下降。非受控下电时电压斜率需低于0.5V/μs,器件生命周期内不得超过400次非受控

一只豌豆象的博客 2042

VTK-9.5.0 1D2D3DWidget实现灰度图+深度图+3D点云显示(可轻松集成到自己的项目)

VTK1D2D3DWidget是一个基于Qt和VTK开发的3D点云可视化工具,支持RGB和深度点云数据的显示与处理。主要功能包括点云加载、可视化、保存为PLY格式文件,以及背景颜色、点间隔、坐标轴显示等参数的自定义设置。该工具采用模块化设计,核心组件包括主窗口管理类、VTK渲染组件和自定义鼠标交互样式,依赖Qt5+和VTK9.5.0库实现跨平台支持。项目提供完整的源码和构建指南,适用于点云数据的快速展示与分析。

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 385

JavaScript的单线程与任务队列

js中任务分为同步任务和异步任务,同步任务是指进入主线程中排队执行的任务,异步任务指的是进入任务队列(事件队列)排队执行的任务,只有主线程中的任务执行完毕后才会调用任务队列的任务,并且遵循先进先出的原则,这也是js运行的机制,而这个过程不断循环被称为事件循环(event loop)

青春木鱼的博客 1383

网络安全系列-四十三:使用Suricata分析恶意流量pcap文件

本文基于[网络安全系列-三十六:使用Suricata IDS分析pcap文件]和 [网络安全系列-四十二: Suricata之rulesets的激活、更新及动态加载]的基础上,使用suricata针对包含恶意流量的pcap文件进行分析,触发事件告警,并对suricata输出的日志进行逐个分析,让你掌握针对恶意流量的分析步骤,及怎么查看suricata输出的日志。

penriver的博客 2886

JS中的任务队列(详解)

说起任务队列的话,首先我们要回顾一下JS语言的特点。 我们知道,Javascript 这门脚本语言诞生的使命就是为处理页面中用户的交互,以及操作 DOM 而诞生的。 所以JS的设计就是单线程的,总不能多线程来操作DOM结构吧(那不就乱套了吗)。 那么什么是单线程,其实就是任务一个接着一个做,不能同时处理多个任务。 那这样就会导致一个问题,如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。 那JS是如何解决这个问题呢?我用一张图来说一下: 有一说一我这个图画的是真的好!

weixin_46726346的博客 4884

OpenClaw部署太难?汉化版+中文社区+国产替代品,国内用户零门槛指南

OpenClaw作为GitHub 10万+星的开源AI助手平台,近期在国内AI圈备受关注 🌟 但部署难度和英文界面让很多用户望而却步。本文整理了针对国内用户的友好资源和简便替代方案,帮助国内用户零门槛上手AI助手工具 🚀

XiaoqiangClub的博客 5758

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

了解JavaScript中的异步处理(1)执行模型和任务队列

目标人物和目的 我知道如何实现异步处理,但有时我不知道最佳做法,因为我不知道它的工作原理 由于对执行顺序的保证不甚了解,有些变化不能放心地进行部署 我想更多地了解它的工作原理,以便我能够更系统地实施它 文章目录目标人物和目的JavaScript执行模型原子性工作队列web浏览器任务队列Node.js任务队列setTimeoutNode.js摘要 JavaScript执行模型 JavaScript执行模型嵌套在 Agent Cluster → Agent → Realm 中,如下图所示。HTML规范还规定

前端仙人的博客 869

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

JavaScript任务队列的顺序机制(事件循环)

同步与异步模式简介 我们知道,Javascript语言的执行环境是单线程(single thread)的。 所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。 这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就...

happyqyt的专栏 8577

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

了解JavaScript中的异步处理(1)执行模型和任务队列(1)

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取!是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取![外链图片转存中…(img-Ujp4TaFm-1712273871825)]

sgegv的博客 800

JavaScript任务队列:理解异步编程的关键

本文将介绍JavaScript任务队列的概念和原理,以及它在异步编程中的作用。JavaScript任务队列是异步编程的核心。了解任务队列的工作原理对于开发者来说具有重要意义。掌握任务队列的使用可以帮助我们更高效地处理异步任务,提高应用程序的响应速度。

你若盛开,清风自来 1452

理清JavaScript执行机制(Event Loop),任务队列、宏任务和微任务

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。 JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程。

青颜的天空的博客 585

js的事件循环和任务队列

js 异步、栈、事件循环、任务队列 在开发中经常遇到js的异步问题,为了方便理解,记录下来,随时回顾。 以下的所有代码都是在浏览器环境下运行 在浏览器中js的运行是依赖浏览器js引擎来解析的,并且是在一定的runtime(运行时)的环境被调用,被执行。由于js引擎是单线程的,所以在执行dom渲染,script引入的时候这些操作是同步的,js引擎会通过 Event Loop 的机制,按顺序把任务...

weixin_30369041的博客 181

构建 JS 中的异步任务队列和发布-订阅架构

在 JS 中构建异步任务队列和发布-订阅架构可以有效利用 JavaScript 的并发模型和性能。 ### 1. 异步任务队列: 对于异步任务队列,你可以使用 async 库,但我们可以使用原生 JavaScript 的 Promise 和 setTimeout 来构建一个简单的任务队列。

hongfu951的专栏 1518

JavaScript 阻塞方式实现异步任务队列

问题 有个需求,需要实现一个异步任务队列,并依次处理队列中的所有任务,具体如下: 随机时间增加异步任务到队列中 队列中的任务按照先进先出的规则依次执行 任务为异步请求,等一个执行完了再执行下一个 这个需求若使用Java语言的BlockingQueue很容易实现,但是JavaScript没有锁机制,实现起来就不那么容易。 方案一 很容易想到使用同步非阻塞方案,每隔一定的时间去检测一下队列中有无任务,有则取出第一个处理。这里检测间隔间隔500毫秒,使用setTimeout模拟异步请求。 <body&g

milugloomy的博客 3736

js实现一个任务队列

functionEventQueue(delayTime){ this._delayTime=delayTime||20; this._queue=[]; this._canRun=true } EventQueue.prototype={ add:function(fn,params){ this._queue.push...

小菜鸡的菜园子 1829

JS单线程与任务队列

javascript单线程与任务队列 一、JavaScript为什么设计为单线程? JavaScript语言的一大特点就是单线程,换言之就是同一个时间只能做一件事。 for(var j = 0; j < 100000; j++) { console.log(j); } console.log('end'); 上面的代码,只有for循环执行完毕,才会执行end; JavaScript的...

470

js中任务队列分类及特点

任务队列 (消息队列) 任务队列介绍 是一个有序的任务集合列表(放的都是异步任务),在js中任务队列可以有多个 当代码里有异步操作的时候,就会把异步操作分发到对应的任务对列里 每一个任务都会有任务源 一个队列里可以放多个任务,任务的读取方式为先进先出 Macro Task 和 Micro Task 宏任务 微任务 DOM操作 (UI rendering) Promise ...

leedh_码农 802
上一篇: javascript闭包
下一篇: ES6项目构建
景洪在编程
博客等级 码龄9年 13粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值