1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
// Copyright © 2022, 飞麦 <[email protected]>, All rights reserved. // 本程序展示异步程序的部分用法 // async: 表明本函数为异步函数, 且此函数内部通常有 await 关键字 // await: 表明将执行权归还调度系统, 当调度系统察觉有空时继续执行, 并等待其后的表达式(通常为异步的)的最终执行结果 // 各秒表的起始时刻字典 const map = new Map(); // 各异步程序的承诺数组 const promise_a = new Array(10); // 输出带有当前时刻的日志(对象) function log(obj) { // 输出当前时刻及对象内容 console.log(`${new Date().toISOString()} ${obj}`); } // 启动秒表(秒表名) function start(name) { // 输出秒表名 log(`Start ${name}`); // 获取高精度时钟的当前时刻[毫秒], 并记录到本秒表的启动时刻中 map.set(name, performance.now()); } // 停止秒表(秒表名) function stop(name) { // 获取高精度时钟的当前时刻[毫秒] const cur_time = performance.now(); // 获取本秒表的启动时刻[毫秒] const old_time = map.get(name); // 计算差值并转换为纳秒 const ns = Math.round((cur_time - old_time) * 1_000_000); // 输出秒表名及纳秒数 log(`Stop_ ${name} ${ns}ns`); } // 统计重复数值(排序后的随机数组) function count_dup(rnd_a) { // 重复数值计数 let dup_num = 0; // 前一个元素 let old = null; // 对排序后的随机数组中的每个元素 for (const ele of rnd_a) { // 如果当前元素的与前一个元素相等 if (ele == old) { // 重复数值计数加一 dup_num++; } else { // 将前一个元素设置为当前元素 old = ele; } } return dup_num; } // 需要较长时间的异步函数(索引) async function busy(idx) { // 本异步函数立即返回, 将程序的调度权归还给调度系统 await null; // 调度系统空闲时继续执行下列语句 // 确定秒表名 const tname = `BUSY_${idx}`; // 启动秒表 start(tname); // 生成一千个元素的数组 const rnd_a = new Array(1_000); // 将数组的所有元素填充为随机整数 for (let idx = 0; idx < rnd_a.length; idx++) { rnd_a[idx] = Math.round(Math.random() * rnd_a.length); } // 对数组进行排序 rnd_a.sort(); // 统计数组中的重复数值 const result = count_dup(rnd_a); // 输出数组中的重复数值 log(`${tname} result=${result}`); // 停止秒表 stop(tname); return result; } // 生成新的承诺(索引) function new_promise(idx) { // 确定秒表名 const pname = `Promise_${idx}`; // 启动秒表 start(pname); // 生成新的承诺, 注意异步程序的返回值被自动包装为 Promise 类型 const promise = busy(idx); // 停止秒表 stop(pname); return promise; } // 生成所有承诺() function prepare() { // 启动秒表 start('prepare'); // 对承诺数组下标循环 for (let idx = 0; idx < promise_a.length; idx++) { promise_a[idx] = new_promise(idx); } // 停止秒表 stop('prepare'); } // 执行各异步函数并统一等待() async function unify() { // 启动秒表 start('Promise.unify'); // 等待所有承诺完成并获得结果数组 const result_a = await Promise.all(promise_a); // 输出结果数组 log('unify return ' + result_a); // 停止秒表 stop('Promise.unify'); return result_a; } // 执行各异步函数并逐个等待() async function every() { // 启动秒表 start('Promise.every'); // 待返回的结果 const result_a = []; // 对承诺数组的元素与下标循环 for (const [idx, promise] of Object.entries(promise_a)) { // 确定秒表名 const sname = `STEP_${idx}`; // 启动秒表 start(sname); // 等待当前承诺结果并放入结果数组 result_a.push(await promise); // 停止秒表 stop(sname); } // 输出结果数组 log('every return ' + result_a); // 停止秒表 stop('Promise.every'); return result_a; } // 主程序() function main() { // 启动秒表 start('main'); // 生成所有承诺 prepare(); // 执行各异步函数并逐个等待[先执行, 但因速度慢后完成] every(); // 生成所有承诺 prepare(); // 执行各异步函数并统一等待[后执行, 但因速度快先完成] unify(); // 停止秒表 stop('main'); } main(); |