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. 6.14 YZBOI模拟赛solution

    \(6.14\ YZBOI\)模拟赛\(solution\) 本来不想写题解来着...毕竟是自己找的题还是写一写吧 上午为了整活,就把赛制改成\(IOI\)赛制了,于是乎拯救了大家的\(70pts\) ...

  2. 5.4 NOI模拟

    \(5.4\ NOI\)模拟 \(T1\) 想到分讨,但是暴力输出一下方案之后有很多特别的情况要讨论,就弃了... 假设\(a\)是原序列,\(b\)是我们得到的序列 设\(i\)是最长公共前缀,\( ...

  3. DP选讲

    $DP$选讲直接上题吧放个题单[各省省选DP](https://www.luogu.com.cn/training/151079)$P5322[BJOI2019]$排兵布阵一眼题,考虑$dp[i][j ...

  4. 为什么企业不愿意升级ERP系统

    前段时间看到一篇文章讲企业为何不愿意升级内部系统的文章,觉得有意思,也想聊聊为何大部分企业不愿意升级ERP的事情. 老东家用的ERP是QAD系统,92年版本,没有图形界面,用户都是通过NetTerm等 ...

  5. 只要9.9元!零基础学习MySQL

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 导语 经过一段时间的筹备和整理,万里数据库<零基础学习MySQL>课程正式在腾讯课堂上线了. 课程地址:htt ...

  6. Luogu1655 小朋友的球 (组合数学,第二类斯特林数,高精)

    我bingoyes再高精用STL就饿死,死外边! string真的爽... 斯特林数模板题:\(S(n,m) = S(n-1,m-1)+S(n-1,m)*n\) #include <iostre ...

  7. 技术专家说 | 如何基于 Spark 和 Z-Order 实现企业级离线数仓降本提效?

    [点击了解更多大数据知识] 市场的变幻,政策的完善,技术的革新--种种因素让我们面对太多的挑战,这仍需我们不断探索.克服. 今年,网易数帆将持续推出新栏目「金融专家说」「技术专家说」「产品专家说」等, ...

  8. Dynamic CRM一对多关系的数据删除时设置自动删除关联的数据

    在业务实体中主子表非常常见,然后子表可能有会有自己的子表或者多对多关系,在删除的业务场景下,删除主数据,剩余的子数据就成了脏数据, 之前的做法是,监听主表的删除事件,然后在插件中找到其下的子表数据然后 ...

  9. HOSMEL:一种面向中文的可热插拔模块化实体链接工具包

    HOSMEL: A Hot-Swappable Modularized Entity Linking Toolkit for Chinese ACL 2022 论文地址:https://aclanth ...

  10. echarts学习笔记(一)

    echarts学习笔记(一) echarts开发步骤 创建一个新的html文件 在html文件head头部信息中导入echarts 声明一个容器(可以理解为画布),用于存放echarts 实例化ech ...