const sleep = (time) => {
return new Promise((resolve) => setTimeout(resolve, time))
}
const doSomething = async () => {
for (let i = 0; i < 100; i++) {
await sleep(1000)
console.log(i)
}
}
doSomething()
为什么这个承诺像预期的那样工作?我在学习"承诺"的事,被困在这上面了。传入Promise构造函数的函数没有reject(),但它仍在工作。
代码片段来自本文:https://medium.com/javascript-in-plain-english/javascript-slow-down-for-loop-9d1caaeeeeed我也很难理解文章中关于setTimeout方法(不起作用)与setTimeout方法(起作用)之间差异的解释。
谢谢你对这个话题的指点。
参数在JavaScript中是可选的,所以reject
参数会被忽略。
至于为什么第一个例子不起作用,是因为setTimeout
为事件循环注册了一个事件,以便将来调用。JavaScript中的东西不会阻塞。内部await
重写代码,使其不阻塞,但代码仍然读取为同步,但它不是。
有很多很好的例子解释了JavaScript事件循环,我强烈建议你去读一下。
直到调用resolve
("res"
)函数才解析Promise
。传递给setTimeout
的函数直到超时结束才运行。
这里是另一个示例,其中resolve
函数返回传入的count
。
const main = async () => {
const done = await doSomething(10, 1000, i => console.log(i));
console.log('Done!');
};
const doSomething = async (times, duration, callback) => {
for (let counter = 0; counter < times; counter++) {
const count = await sleep(counter, duration);
callback(count);
}
return true;
};
const sleep = (count, duration) => {
return new Promise((res) => setTimeout((n) => res(n), duration, count));
};
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }
这是一个少耦合的版本,带有一些默认参数。
const DEBUG = true;
const main = async () => {
const worker = (n, m) => console.log(`Step ${n + 1}/${m}`);
await doSomething(worker);
};
const doSomething = async (callback, duration = 1000, times = 10) => {
if (DEBUG) console.log('Start!');
for (let counter = 0; counter < times; counter++) {
await sleep(duration, counter, times);
callback(counter, times);
}
if (DEBUG) console.log('Done!');
return true;
};
const sleep = (duration, count = 1, times = 1) => {
return new Promise(res => setTimeout(res, duration));
};
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }