在学习javascript中的async时,我遇到了javascript中sleep()函数的最佳实践。
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
sleep() 的 JavaScript 版本是什么?
在 w3school 的setTimeout
文档中,它说第一个参数必须是计时器解析时将调用的函数。因此,如果 resolve 是一个函数,它是否只是因为它从未实现而跳过?
这到底是怎么回事?我有点阅读障碍,如果这是显而易见的,我很抱歉。
它们都是一样的。
您提供的第一个示例,如果完整编写,如下所示:
函数睡眠(毫秒) { 返回新的承诺((解析) => { 返回集超时(解析,毫秒) }); }
(注意:这是你的第一个函数,而不是你的第二个函数 - 尽管它们本质上是相同的,但我想强调的是,这是对你第一个函数的重写)
也就是说,您正在传递匿名函数:
(resolve) => {
return setTimeout(resolve, ms)
}
到Promise
.但是,箭头函数的语法允许一些快捷方式。
第一个快捷方式是,如果函数只有一个语句,则可以省略{}
。也就是说,上面的函数可以简写为:
(resolve) => setTimeout(resolve,ms);
所以
(resolve) => {
return setTimeout(resolve, ms)
}
和
(resolve) => setTimeout(resolve,ms);
是完全相同的功能,但第二个版本是用速记编写的。
另一个快捷方式是,如果函数只接受一个参数,则可以删除参数周围的()
。所以上面的函数可以改写为:
resolve => setTimeout(resolve,ms);
请注意,这与以下内容完全相同:
(resolve) => {
return setTimeout(resolve, ms)
}
只用速记写。
<小时 />附加答案。
你问
因此,如果 resolve 是一个函数,它是否只是因为它从未实现而跳过?
你错了。它并非从未实施过。它由编写Promise
类的人实现。
以下是Promise
类的作用:
如果你调用我作为构造函数,那么你需要向我传递一个带有两个参数的函数。稍后我将使用两个参数调用您的函数,这两个参数都是您可以调用的函数。如果你调用第一个函数,那么我会假设你没问题。如果你调用第二个函数,那么我将假设有一个错误。
仅此而已。这两个参数(通常称为resolve
和reject
,但您可以将它们命名为任何名称)由Promise
类定义,并在Promise
类调用函数时传递给您的函数。
下面是我自己的Promise
类的示例实现,用于演示正在发生的事情:
// Warning. For illustration purposes only. This class does not
// fully implement the Promise design pattern as specified by ECMA262:
class Promise {
constructor (yourfunction) {
this.result = undefined;
this.error = undefined;
function resolve (x) {this.result = x};
function reject (y) {this.error = y};
yourfunction(resolve,reject); // calling your function!!
}
then (yourcallback) {
yourcallback(this.result);
}
catch (yourcallback) {
if (this.error) yourcallback(this.error);
}
}
具有单个参数的箭头函数的参数列表两边的括号是可选的。这两种语法完全相同:
resolve => …
(resolve) => …
使用哪一个是样式首选项,而不是最佳实践问题。
包含多个参数的箭头函数参数列表始终需要括号。
const add = (a, b) => a + b;
add(1, 2)
// returns 3
括号不表示函数调用,就像(ms)
不是function sleep(ms)
中的函数调用一样。