我什么时候应该在打字稿中使用回调函数?

时间:2019-10-04 02:42:02

标签: typescript

我曾经编码C / C ++,而我刚开始学习TS。让我特别困惑的一件事是,TS并非总是自上而下运行。像下面的示例一样,它将显示“ 2 1”。

<iframe src="https://your-url.com/file.doc">

但是我怎么知道一个功能是否可以足够快地执行,以便程序可以以自上而下的模式运行?而且,如果我在整个程序中继续使用递归调用 simulation 自上而下的模式,我可以想象,那将是一团糟。

3 个答案:

答案 0 :(得分:3)

您需要学习基本的JavaScript才能理解其工作原理。有一个称为“事件循环”的事件正在引起这种现象。简而言之,当执行堆栈中的所有进程时,setTimeout函数进入回调队列并进入回调堆栈(进程从回调堆栈执行)。您可以做一件有趣的事。将时间设置为0,看看会发生什么。

javascript不是异步语言。这个事件循环的概念使javascript异步工作,但在幕后一切都像在c / c ++中一样同步工作

答案 1 :(得分:1)

Typescript在编译时被转换为Javascript。因此,在运行时,周围没有Typescript,只有Javascript。

JavaScript引擎实现了两个队列:事件队列和微任务队列。后者具有更高的优先级,并由Promises使用。

考虑此代码及其打印输出:

console.log('start');
setTimeout(function() {                               // queue to event queue                  
  console.log('timeout');
}, 0);
Promise.resolve().then(function() {                  // queue to microtask queue     
  console.log('promise1');
}).then(function() { console.log('promise2'); });    // queue to microtask queue
console.log('end');



start
end             // current call stack empty after printing so look at the queues
promise1        // dequeue and process a task from microtask queue
promise2        // keep doing the above ignoring the main event queue
timeout         // microtask queue empty so do dequeue and process an event from event queue

答案 2 :(得分:0)

可以说,在2019年,您永远不要使用回调。相反,您应该使用Promise

这允许开发人员选择使用回调还是使用更现代的异步/等待方式

示例:

function first() {
  // Simulate a code delay
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(1);
      resolve();
    }, 500);
  });
}

function second() {
  console.log(2);
}

(async() => {
  await first();
  second();
})();

function first() {
  // Simulate a code delay
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(1);
      resolve();
    }, 500);
  });
}

function second() {
  console.log(2);
}

first().then(second);

我们也可以包装setTimeout本身

function wait(ms = 0) {
 return new Promise(resolve => setTimeout(resolve, ms));
}

async function first() {
  await wait(500);
  console.log(1);
}

function second() {
  console.log(2);
}

(async() => {
  await first();
  second();
})();

另一个示例显示使用promises使异步/等待成为可能,这使您的代码易于遵循,避免了您提到的嵌套地狱

function wait(ms = 0) {
 return new Promise(resolve => setTimeout(resolve, ms));
}

async function main() {
  await wait(1000);
  console.log('Each')
  await wait(1000);
  console.log('Of')
  await wait(1000);
  console.log('These');
  await wait(1000);
  console.log('Messages');
  await wait(1000);
  console.log('appears');
  const words = ['one', 'second', 'after', 'the', 'previous']
  for (const word of words) {
    await wait(1000);
    console.log(word);
  }
}
main();

如果您是C / C ++的JavaScript / TypeScript的新手,您应该了解closures,因为与C / C ++不同,您永远没有理由为 userdata 提供参数回调。

就像@Sudip Sarker在event loop上提到的一样,JavaScript是单线程的,并且在“事件循环”上运行。并行运行的部分位于浏览器本身和JavaScript调用的API中(加载图像,调用访存,等待超时等)。 JavaScript本身一次只运行一个“事件”,然后退出以等待下一个事件。