在测试中,我发现JavaScript Promises 始终是异步的,无论它们是否在其链中包含任何异步函数.
以下是一些显示控制台中操作顺序的代码.如果运行它,您将看到即使每个函数都是同步的,输出也会显示两个aPromise()并行运行的调用,并且在运行2完成之前"surprisingly this happens after run 2 finishes" 不会发生.
function aPromise() {
return new Promise(function(resolve, reject) {
console.log("making promise A")
resolve(bPromise());
console.log("promise A resolved")
});
}
function bPromise() {
return new Promise(function(resolve, reject) {
console.log("making and resolving promise B")
resolve();
});
}
aPromise().then(function() {
console.log("finish run 1");
}).then(function() {
console.log("surprisingly this happens after run 2 finishes");
});
aPromise().then(function() {
console.log("finish run 2");
})Run Code Online (Sandbox Code Playgroud)
输出到控制台:
making promise A
making and resolving promise B
promise …Run Code Online (Sandbox Code Playgroud) 我只是想提高我对 JavaScript Promises 工作原理的理解。我创造了以下情况:
LOG 'FOO'
RUN CALLBACK LOGGING 'CALLBACK'
LOG 'BAR'
Run Code Online (Sandbox Code Playgroud)
期望所有功能立即完成(我的意思是它们不会花费过多/未知的时间来完成,您将使用异步操作来完成)以便上述操作顺序将按该顺序发生。
您可以通过以下方式编写:
function foo(cb) {
// LOG 'FOO'
console.log('foo');
// RUN CALLBACK
cb();
}
function callback() {
// LOG 'CALLBACK'
console.log('callback');
}
foo(callback);
console.log('bar');
Run Code Online (Sandbox Code Playgroud)
这会根据我在开始时指定的情况产生预期的输出。
> foo
> callback
> bar
Run Code Online (Sandbox Code Playgroud)
您也可以通过以下方式编写它:
function foo() {
return new Promise((resolve) => {
// LOG 'FOO'
console.log('foo');
return resolve(null);
});
}
function callback() {
// LOG 'CALLBACK'
console.log('callback');
}
foo().then(callback);
// LOG 'BAR'
console.log('bar');
Run Code Online (Sandbox Code Playgroud)
这种情况会产生以下结果:
> foo …Run Code Online (Sandbox Code Playgroud) timer = window.setTimeout(function () {
//do something
window.setTimeout(arguments.callee, 1000);
}, 1000);
Run Code Online (Sandbox Code Playgroud)
结果是这些代码运作良好.
但为什么不导致下面的错误?
超出最大调用堆栈大小
在调试它时,找到变量范围不包括先前执行的"setTimeout函数"的范围
谁能解释一下?
最好是文档.
我遇到了一个函数,它的setTimeout内部超时呈指数级增长(timeout *= 2).
let timeout = 10000
function foo() {
// doSomething without breaking, returning
setTimeout(foo, timeout)
timeout *= 2;
}
foo()
Run Code Online (Sandbox Code Playgroud)
看起来这不应该是一个问题,并且直觉上感觉setInterval有点已经做了同样的事情(有一个无限循环,直到它被取消,如果有的话),然而,我的问题在于方法本身.
javascript ×4
promise ×2
asynchronous ×1
browser ×1
ecmascript-6 ×1
es6-promise ×1
function ×1
loops ×1
paradigms ×1
settimeout ×1
synchronous ×1