How to get the return value of the setTimeout inner function in js All In One

How to get the return value of the setTimeout inner function in js All In One

在 js 中如何获取 setTimeout 内部函数的返回值
Promise wrap& Async / Await
How to get the return value of the setTimeout inner function in js All In One

文章插图
raise a question
提出问题
如何获取 setTimeout 的返回值 , 以便可以自动化测试 , 即可以使用测试用例模版 , 跑通所有测试用例?
error
How to get the return value of the setTimeout inner function in js All In One

文章插图
question analysis
问题分析
正常思路下 , 是不可能实现的 , 因为 setTimeout 是一个异步宏任务不会阻塞 js 单线程的执行 , 优先级最低 , 最后才会被执行;故测试用例中执行读取结果的代码逻辑获取不到它的返回值 , 即测试代码逻辑已经执行了 , 结果还没返回;
那既然 setTimeout 是异步的 , 那就想办法阻塞它 , 让它的结果先返回 , 然后再执行读取结果的代码逻辑;所以很容易想到使用 Promise 把 setTimeout 包装成一个微任务 , 然后通过 Async/Await 来进行异步流程的控制
Try it out
尝试验证
"use strict";/** * * @author xgqfrms * @license MIT * @copyright xgqfrms * @created 2022-10-18 * @modified * * @description js debounce * @descriptionjs debounce * @difficulty Medium * @time_complexity O(n) * @space_complexity O(n) * @augments * @example * @link https://www.cnblogs.com/xgqfrms/p/13849482.html * @solutions * * @best_solutions * */const log = console.log;// function debounce(func) {//var id;//return function (args) {//console.log(`args 1 =`, args);//var context = this;//// var args = arguments;//clearTimeout(id);//id = setTimeout(() => {//// func.apply(context, args);//// func.apply(context, [...args]);//func.apply(context, ...args);//// Uncaught TypeError: Spread syntax requires ...iterable[Symbol.iterator] to be a function//});//};// };// function debounce(func, delay) {//let id;////...rest 保证在不使用 arguments 的情况下 , 也可以传入不定数量的参数//return function (...args) {//console.log(`\nrest args =`, args);//console.log(`rest ...args =`, ...args);//console.log(`rest [...args] =`, [...args]);//let args1 = arguments;//let args2 = Array.prototype.slice.call(arguments, 0);//console.log(`args1 =`, args1);//console.log(`args2 =`, args2);//let context = this;//// let that = this;//clearTimeout(id);//id = setTimeout(() => {////apply 接受参数数组 [arg1, arg2, ...]//func.apply(context, args);//// func.apply(context, [...args]);//// func.apply(context, ...args);//// Uncaught TypeError: CreateListFromArrayLike called on non-object////call 接受参数列表 (arg1, arg2, ...)//func.call(context, ...args2);//}, delay);//};// };const debounce = (func, delay) => {let id;//...rest 保证在不使用 arguments 的情况下 , 也可以传入不定数量的参数return async (...args) => {console.log(`\nrest args =`, args);console.log(`rest ...args =`, ...args);console.log(`rest [...args] =`, [...args]);let context = this;// let that = this;clearTimeout(id);// id = setTimeout(() => {////apply 接受参数数组 [arg1, arg2, ...]//func.apply(context, args);//// func.apply(context, [...args]);////call 接受参数列表 (arg1, arg2, ...)//// func.call(context, ...args);// }, delay);const promise = new Promise((resolve, reject) => {id = setTimeout(() => {resolve(func.apply(context, args));}, delay);});// return promise;const result = await(promise);console.log(`result`, result);return result;// js how to get setTimeout inner function return valuepromise wrap& async / await};};// function test (a, b, c, d) {//const args = [...arguments];//console.log(`test args =`, args);// }// const fn = debounce(test, 1000);// fn(1,2,3);// // fn(1,2,3,4);// fn(1,2,3,4,5);// 测试用例 test casesconst testCases = [{input: [1,2,3],result: '1,2,3',desc: 'value equal to "1,2,3"',},{input: [1,2,3,4],result: '1,2,3,4',desc: 'value equal to "1,2,3,4"',},{input: [1,2,3,4,5],result: '1,2,3,4,5',desc: 'value equal to "1,2,3,4,5"',},];function test (a, b, c, d) {const args = [...arguments];console.log(`test args =`, args);return args;}const func = debounce(test, 1000);log(`func =`, func);// func = [AsyncFunction (anonymous)]// func = Promise { [Function (anonymous)] }(async () => {for (const [i, testCase] of testCases.entries()) {async function testCaseAsyncFunc(i, testCase) {const result = await func(...testCase.input);log(`result =`, result);// result = Promise { <pending> }// TypeError: func is not a functionlog(`test case ${i} result: `, result.join() === testCase.result ? ` passed` : ` failed`, result);// log(`test case ${i} =`, testCase);}await testCaseAsyncFunc(i, testCase);}})();

经验总结扩展阅读