我曾经编码C / C ++,而我刚开始学习TS。让我特别困惑的一件事是,TS并非总是自上而下运行。像下面的示例一样,它将显示“ 2 1”。
<iframe src="https://your-url.com/file.doc">
但是我怎么知道一个功能是否可以足够快地执行,以便程序可以以自上而下的模式运行?而且,如果我在整个程序中继续使用递归调用 simulation 自上而下的模式,我可以想象,那将是一团糟。
答案 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本身一次只运行一个“事件”,然后退出以等待下一个事件。