理解setTimeout及其在JavaScript中的实现
我有以下代码:理解setTimeout及其在JavaScript中的实现,javascript,promise,settimeout,es6-promise,Javascript,Promise,Settimeout,Es6 Promise,我有以下代码: function MyPromise(configFunction) { let nextSuccessCallBack = undefined; let nextResolve = undefined; configFunction(function(message){ setTimeout(function(){ if(nextSuccessCallBack) { var result = nextSuccessCallBack
function MyPromise(configFunction) {
let nextSuccessCallBack = undefined;
let nextResolve = undefined;
configFunction(function(message){
setTimeout(function(){
if(nextSuccessCallBack) {
var result = nextSuccessCallBack(message);
if(result && result.then) {
result.then(nextResolve);
} else {
nextResolve && nextResolve(result);
}
}
})
});
return {
then: function(successCallback) {
nextSuccessCallBack = successCallback;
return new MyPromise(function(resolve) {
nextResolve = resolve;
})
}
}
}
new MyPromise(function(resolve, reject) {
resolve('new message');
}).then(function(message) {
console.log(message);
return 'another message'
}).then(function(message) {
console.log(message)
console.log('here')
})
let p = new MyPromise(resolve => resolve("value"));
p.then(console.log); // This callback is called
p.then(console.log); // This callback is not called -> violation!
在本例中,
nextSuccessCallBack
似乎被设置为中的回调函数。然后
,然后它在setTimeout函数中的值现在被填充。然而,这让我感到困惑。我认为当我们到达构造函数中的return
语句时,我们返回对象并有效地停止函数?如果是这样的话,那么程序是如何到达设置超时的呢?代码片段中的代码确实解决了这个问题,但是,按照更好的代码效率和理解方式,它是一个混乱的承诺的糟糕实现
上述代码也可以这样编写:
const examplePromise = new Promise((resolve, reject) => {
resolve("Another Message");
});
console.log("New Message");
examplePromise.then((message) => {
console.log(message);
});
现在,为了更好地理解JavaScript中承诺的概念,我将举另一个例子:
假设我想创建一个程序,它会说你好,然后在2秒钟后说你好吗?
有两种方法可以解决这个问题
- 只需使用
setTimeout()
函数,该函数在一定时间后执行函数
- 使用带有
setTimeout()的承诺
案例一(使用):
案例二(使用)
现在,对于简单的情况,如在2秒后记录消息,不需要承诺。您可以使用它们(没问题),但实际上,承诺
用于以下情况:等待函数执行数据库查询,或者需要等待服务器给您一些HTML响应,或者在使用WebAPI时,等等
注:setTimeout()
只是一个例子。在编写承诺时,您不必总是使用setTimeout()
。如果使用WebAPI获取数据,通常会编写$.ajax(…)。然后(…)
或获取(…)。然后(…)
而不是设置超时()
,这不是正确的Promise实现。它显然没有拒绝功能,但也没有实现它不符合的实现功能。举两个例子:
它不符合规则2.1.2.2
履行承诺时,承诺必须有一个价值,这个价值不能改变
..也不适用规则2.2.2.3:
如果oncompleted
是一个函数,则不能多次调用它
在实现中,如果要添加第二个对resolve
的调用:
new MyPromise(function(resolve, reject) {
resolve('new message'); resolve('new message2');
}).then((function(message) {
console.log(message);
// ... etc
})
…然后对resolve
的两个调用都将触发then
回调,并显示承诺的值在第一次设置后已被修改。这完全违反了承诺的原则:承诺只能解决一次
它不符合规则2.2.6:
则
可能会在同一承诺上被多次调用
- 如果履行了
承诺
,则所有相应的oncompleted
回调必须按照其对的原始调用的顺序执行,然后
如果我们使用以下代码,则不会发生这种情况:
function MyPromise(configFunction) {
let nextSuccessCallBack = undefined;
let nextResolve = undefined;
configFunction(function(message){
setTimeout(function(){
if(nextSuccessCallBack) {
var result = nextSuccessCallBack(message);
if(result && result.then) {
result.then(nextResolve);
} else {
nextResolve && nextResolve(result);
}
}
})
});
return {
then: function(successCallback) {
nextSuccessCallBack = successCallback;
return new MyPromise(function(resolve) {
nextResolve = resolve;
})
}
}
}
new MyPromise(function(resolve, reject) {
resolve('new message');
}).then(function(message) {
console.log(message);
return 'another message'
}).then(function(message) {
console.log(message)
console.log('here')
})
let p = new MyPromise(resolve => resolve("value"));
p.then(console.log); // This callback is called
p.then(console.log); // This callback is not called -> violation!
这些都是基本的缺点,这只是冰山一角
如果您对如何按照Promise/A+实现它感兴趣,那么请看一看逐步的解释
至于你的问题
程序是如何到达设置超时的
当主代码执行此操作时:
new MyPromise(function(resolve, reject) {
resolve('new message');
})
…然后使用该回调函数初始化参数变量configFunction
。MyPromise
构造函数调用它,并将以下回调作为第一个参数传递给它:
function(message){
setTimeout(function(){
if(nextSuccessCallBack) {
var result = nextSuccessCallBack(message);
if(result && result.then) {
result.then(nextResolve);
} else {
nextResolve && nextResolve(result);
}
}
})
}
这意味着主代码的回调函数中的resolve
是用上述回调函数初始化的。然后,主代码的回调函数使用字符串参数调用resolve
。由于resolve
是上面的回调函数,我们可以看到它是在message
初始化为“newmessage”的情况下执行的。此函数执行setTimeout
configFunction
被调用(这是传递到MyPromise的回调),调用resolve
(这是传递到configFunction
的回调),调用setTimeout
。这是一个非常糟糕的Promise
实现。我一点也不像真正的promise那样工作。“JavaScript编程指南”是什么?另外,我认为OP是想理解他们的算法为什么不起作用,而不是如何使用本地算法……它不会丢失,或者?你可以起草你的问题/答案,只要你想,它不会丢失。因此也会将其保存到本地存储。。。