当前位置: 首页 > 知识库问答 >
问题:

如何从setTimeout回调获取返回值?[重复]

庾奇思
2023-03-14

考虑这个代码

const obj = {
  generate(num) {
    return Math.random()*num;
  },
  add(a,b) {
    return this.generate(a) + this.generate(b)
  }
};

function delay(func, ms) {
  function wrapper() {
    setTimeout(() => func.apply(this, arguments), ms)  // How can I get the return value from the original function?
  }

  return wrapper;
}

// create wrappers
obj.f1000 = delay(obj.add, 1000);
obj.f1500 = delay(obj.add, 1500);

obj.f1000(1,3);
obj.f1500(2,5);

我做了一个包装器来延迟add()的方法调用是否有办法从setTimeout内部的回调中检索值,即this.generate(a)this.generate(b)添加()

共有2个答案

公沈浪
2023-03-14

由于setTimeout将异步执行回调,因此需要使用promise(ES6)或异步/等待(ES7)。

您可以为ES5重新填充它。

const obj = {
  generate(num) {
    return Math.random() * num;
  },
  add(a, b) {
    return this.generate(a) + this.generate(b);
  }
};

// create promise
function timedPromise(func, args, ms) {
  return new Promise(resolve => {
    setTimeout(() => {
      // spread operator
      resolve(func.apply(null, args));
    }, ms);
  });
}

// create a function that creates a promise
function delay(func, ms) {
  function wrapper() {
    return timedPromise(func, arguments, ms);
  }

  return wrapper;
}

// obj.add uses this.generate, but 'this' was not bound to obj
obj.f1000 = delay(obj.add.bind(obj), 1000);
obj.f1500 = delay(obj.add.bind(obj), 1500);

console.info('calculating...')
const result1 = obj.f1000(1, 3);
const result2 = obj.f1500(2, 5);

result1.then(result => {
  console.info('f1000', result);
})

result2.then(result => {
  console.info('f1500', result);
})
闻人冷勋
2023-03-14

只需在包装器中更改此行:

setTimeout(() => func.apply(this, arguments), ms) 

回报promise(ES6)

return new Promise(resolve => setTimeout(() => resolve(func.apply(this, arguments)), ms));

您可以通过访问延迟结果。然后

根据OP的请求更新,编辑答案以使用async/await代替then。由于await需要在声明为async的函数中调用,因此我们需要将js代码封装在新函数中(main()如下):

const obj = {
  generate(num) {
    return Math.random() * num;
  },
  add(a, b) {
    return this.generate(a) + this.generate(b)
  },

};

function delay(func, ms) {
  function wrapper() {
    // CHANGE THIS LINE
    return new Promise(resolve => setTimeout(() => resolve(func.apply(this, arguments)), ms)); // How can I get the return value from the original function?
  }
  return wrapper;
}

//await can only work in an 'async' function
async function main() {
  obj.f1000 = delay(obj.add, 1000);
  console.time('completed');

  // add await here
  let x = await obj.f1000(1, 3); 
  console.log(x);
  console.timeEnd('completed');
}

main();
 类似资料:
  • 问题内容: 我想使用函数在ajax调用中获取值。但是该值始终返回未定义状态。返回值仅为1或0。 这是我的代码: 大家好,仍在努力完成这项工作。我现在得到的值显示为1或0。我现在想要完成的是如何在if语句中实现它。我想吃点这样的东西。如果val=0,则返回true;否则,返回true。否则返回假。我不确定我是否在使用ajax函数的正确轨道上。但是,如果有更好的方法可以告诉我,我将不胜感激。 问题答案

  • 问题内容: 我在互联网上读过有关回调的信息,但就我而言我还是听不懂。 我具有此功能,并且在运行时会记录到控制台。但是,现在我需要在另一个功能中使用此响应,而我正在努力做到这一点。 这是我应该得到的地方:(这显然不起作用,因为它不等待响应。) 我真的很难把头放在回调上,我在这里盯着自己瞎了。 问题答案: 回调无法返回值,因为它们将要返回的代码已经执行。 因此,您可以做几件事。一个传递回调函数,异步函

  • 我想这样做: js中是否有一种方法可以调用同步代码中的函数,并仅在我的controlVar变为1时返回值? 这不应该阻止,因为当我使用setTimeout时,主循环应该能够控制,但是如果阻止对我来说并不重要。 谢谢

  • 问题内容: 我正在使用Microsoft SQL Server JDBC驱动程序2.0通过Java连接到SQL Server(2005)。 如何从存储过程中获取返回值?我正在做类似的事情: 我应该使用execute()吗?executeQuery()?executeUpdate()?这些似乎都不默认返回一个返回值,但是我不确定如何获取它。 编辑1:明确地说,我知道如何调用存储过程。这个问题专门关于

  • 问题内容: 我如何使这个小功能“ imageExists”返回ajax请求是否成功? 问题答案: 我相信您将必须使用同步模式并使用单独的变量来存储返回值。

  • 我正在尝试返回在setTimout中计算的值。但好像我拿不出这个值。我读到要做到这一点,我必须用promise。我是否必须像下面这样使用它:https://italonascimento.github.io/application-a-timeout-to-your-promissions/?