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

在 js 中如何获取 setTimeout 内部函数的返回值

Promise wrap & Async / Await

raise a question

提出问题

如何获取 setTimeout 的返回值,以便可以自动化测试,即可以使用测试用例模版,跑通所有测试用例?

error

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
* @description js 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 value promise 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 cases
const 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 function
log(`test case ${i} result: `, result.join() === testCase.result ? ` passed` : ` failed`, result);
// log(`test case ${i} =`, testCase);
}
await testCaseAsyncFunc(i, testCase);
}
})();

solutions

得出结论

"use strict";

/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2022-10-18
* @modified
*
* @description How to get the return value of the setTimeout inner function in js All In One
* @description 在 js 中如何获取 setTimeout 内部函数的返回值
* @difficulty Hard
* @time_complexity O(n)
* @space_complexity O(n)
* @augments
* @example
* @link https://www.cnblogs.com/xgqfrms/p/16806941.html
* @link https://www.cnblogs.com/xgqfrms/p/13849482.html
* @solutions
*
* @best_solutions
*
*/ const log = console.log; // 1. no need return value
/* function debounce(func, delay) {
let id;
// ...rest 保证在不使用 arguments 的情况下,也可以传入不定数量的参数
return function (...args) {
let that = this;
clearTimeout(id);
id = setTimeout(() => {
// apply 接受参数数组 [arg1, arg2, ...]
func.apply(that, args);
// func.apply(context, [...args]);
// call 接受参数列表 (arg1, arg2, ...)
// func.call(context, ...args2);
}, delay);
};
}; 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); */ // 2. setTimeout with return value
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 that = this;
clearTimeout(id);
const result = await new Promise((resolve, reject) => {
id = setTimeout(() => {
// apply 接受参数数组 [arg1, arg2, ...]
resolve(func.apply(that, args));
}, delay);
});
return result;
// const promise = new Promise((resolve, reject) => {
// id = setTimeout(() => {
// // apply 接受参数数组 [arg1, arg2, ...]
// resolve(func.apply(that, args));
// }, delay);
// });
// const result = await(promise);
// console.log(`result =`, result);
// return result;
};
}; // 测试用例 test cases
const 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)] (async () => {
for (const [i, testCase] of testCases.entries()) {
async function testCaseAsyncFunc(i, testCase) {
const result = await func(...testCase.input);
log(`result =`, result);
log(`test case ${i} result: `, result.join() === testCase.result ? ` passed` : ` failed`, result);
// log(`test case ${i} =`, testCase);
}
await testCaseAsyncFunc(i, testCase);
}
})();

js debounce & js throttle

如何使用 js 实现一个 debounce 函数 All In One

https://www.cnblogs.com/xgqfrms/p/13849482.html

如何使用 js 实现一个 throttle 函数 All In One

https://www.cnblogs.com/xgqfrms/p/13849487.html

refs

https://splunktool.com/how-to-make-javascript-settimeout-returns-value-in-a-function

https://stackoverflow.com/questions/24928846/get-return-value-from-settimeout



xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有️xgqfrms, 禁止转载 ️,侵权必究️!


How to get the return value of the setTimeout inner function in js All In One的更多相关文章

  1. Error 1313: RETURN is only allowed in a FUNCTION SQL Statement

    1.错误描述 14:07:26 Apply changes to rand_string Error 1313: RETURN is only allowed in a FUNCTION SQL St ...

  2. Mysql5.7创建存储过程中调用自定义函数报错Not allowed to return a result set from a function

    因为很多存储过程都会共用一段sql语句,所以我把共用的sql封装成一个自定义函数 AddCapital(); 然后通过存储过程调用,创建存储过程会报错1415,Not allowed to retur ...

  3. C# return dynamic/anonymous type value as function result

    function: public static dynamic GetAppSecret() { //string[] result = new string[] { "", &q ...

  4. layer弹出层 layer源码

    下载源码:点击下载 ;!function(window, undefined){ "use strict"; var pathType = true, //是否采用自动获取绝对路径 ...

  5. HTML5 canvas处理图片的各种效果,包括放大缩小涂鸦等

    http://www.htmleaf.com/ziliaoku/qianduanjiaocheng/201502151385.html jQuery 缩放 旋转 裁剪图片 Image Cropper ...

  6. viewer.js图片查看器插件(可缩放/旋转/切换)

    <!doctype html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  7. JS模版引擎[20行代码实现模版引擎读后感]

    曾经阅读过<只有20行JAVASCRIPT代码, 手把手教你写一个页面模版引擎>这篇文章, 对其中实现模版的想法实在膜拜, 于是有了这篇读后感, 谈谈自己对模版引擎的理解, 以及用自己的语 ...

  8. return

    return作为返回关键字,有以下两种意义的返回格式: 1,返回把握与函数成果:停止函数执行,返回调用函数,并且把函数的值作为返回成果. turn只能退出当前函数,如果多个函数嵌套就不行了,要想整个退 ...

  9. node中的流程控制中,co,thunkify为什么return callback()可以做到流程控制?

    前言 我在学习generator ,yield ,co,thunkify的时候,有许多费解的地方,经过了许多的实践,也慢慢学会用,慢慢的理解,前一阵子有个其他项目的同事过来我们项目组学习node,发现 ...

随机推荐

  1. Vs 快捷键---探索不一样的编程

    前言:现在很多工具都支持各式各样的快捷键,vs作为后起之秀,多功能的快捷键自然是必不可少的, 而且针对单行操作的快捷键是无需选中整行的,只需要光标停留在所操作的代码上面即可. 1.注释:CTRL+K+ ...

  2. LuoguP1131 [ZJOI2007]时态同步 (树形DP,贪心)

    贪心就离根最大距离 #include <iostream> #include <cstdio> #include <cstring> #include <al ...

  3. thinkphp 5 及一下或php项目里实现模糊查询

    想在thinkPHP或者PHP项目实现模糊查询怎么实现呢? 今天在网上搜了一下用 mysql里的 like 就可以实现 怎么用呢? 看代码: 错误用法: where('title','like',$s ...

  4. 一个监控工具monit

    最近看了一个问题,monit监控在读取配置文件之后,访问的文件是残留在容器中的,导致认为服务异常,其实一开始容器启动,并没有对应的服务. [root@10-36-235-119.fin-wealth- ...

  5. 刷题记录:Codeforces Round #724 (Div. 2)

    Codeforces Round #724 (Div. 2) 20210713.网址:https://codeforces.com/contest/1536. div2明显比div3难多了啊-只做了前 ...

  6. spring项目中starter包的原理,以及自定义starter包的使用

    MAVEN项目中starter的原理 一.原始方式 我们最早配置spring应用的时候,必须要经历的步骤:1.pom文件中引入相关的jar包,包括spring,redis,jdbc等等 2.通过pro ...

  7. Maven 过滤问题

    <build> <resources> <resource> <directory>src/main/resources</directory&g ...

  8. CMake | 将路径添加到 CMAKE_PREFIX_PATH

    1. CMAKE_PREFIX_PATH CMAKE_PREFIX_PATH是一个分号分隔的路径列表,用来指明软件/库安装路径前缀,以供find_package(),find_program(),fi ...

  9. Windows Server Backup保留副本数量的问题

    在配置Windows Server Backup的时候可以配置备份时间点和备份存放位置,但是无法配置保留备份的数量.作为微软提供的一个基本的备份工具,做简单的备份还是可以的.但是对于同一备份任务,反复 ...

  10. 安装vm,在vm中安装windows10操作系统。

    步骤:双击打开虚拟机文件 根据向导安装  下一步 然后等待安装 安装好了后点击许可证 ZF3R0-FHED2-M80TY-8QYGC-NPKYF YF390-0HF8P-M81RQ-2DXQE-M2U ...