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. 妙用 CSS 构建花式透视背景效果

    本文将介绍一种巧用 background 配合 backdrop- filter 来构建有趣的透视背景效果的方式. 本技巧源自于一名群友的提问,如何构建如 ElementUI 文档的一种顶栏背景特效, ...

  2. 万答#1,MySQL中如何查询某个表上的IS(意向共享)锁

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 问题 问题原文是这样的: 假如在MySQL事务里,给某个表的一行加了 共享锁,理 ...

  3. Golang基础教程

    以下使用goland的IDE演示,包含总计的golang基础功能共20个章节 一.go语言结构: 二.go基础语法: 三.变量 四.常量 五.运算符 六.条件语句 七.循环 八.函数 九.变量作用域 ...

  4. ArkUI 组件 Props

    在上一篇博客文章中简单地提到了 Props . 在使用 Props 时需要注意到一个点,子组件从寄主页面传递过来的值是单向的,也就是子组件不能直接修改传递下来的值,即单向性. 以上篇文章定义的头像组件 ...

  5. [CF1539F] Strange Array (线段树)

    题面 有一个长度为 n \tt n n 的序列 a \tt a a ,对于每一个位置 i ∈ [ 1 , n ] \tt i\in[1,n] i∈[1,n]: 选择一个区间 [ l , r ] \tt ...

  6. 长篇图解etcd核心应用场景及编码实战

    大家好啊,我是字母哥,今天写一篇关于etcd的文章,其实网上也有很多关于etcd的介绍,我就简明扼要,总结提炼,期望大家通过这一篇文章掌握etcd的核心知识以及编码技能! 本文首先用大白话给大家介绍一 ...

  7. awk5个使用场景

    awk简介 首先要知道awk的使用场景,需了解awk有哪些优势与短板. 关于个人近期学习awk总结其优势: awk对文本的处理运算效率同比其他工具效率高很多(比shell的for循环高10倍以上,运算 ...

  8. 【Android 逆向】switch 的smail特征

    JAVA 源码 ... String str1 = packedSwitch(1); ... private String packedSwitch(int i) { String str = nul ...

  9. [Qt基础内容-08] Qt中MVC的M(Model)

    Qt中MVC的M(Model)简单介绍 Qt有自己的MVC框架,分别是model(模型).view(视图).delegate(委托),这篇文章,简单的介绍以下Qt中有关model(模型)的类以及一些基 ...

  10. 【设计模式】Java设计模式 - 适配器模式

    [设计模式]Java设计模式 - 适配器模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一 ...