C#/ Dart的async / await功能让我有点失望。我注意到ES7有类似语法的提议,there is a library将该功能添加到Node.JS应用程序。
此库在浏览器中不起作用。我想通过尝试编写我自己的迷你解决方案可能会帮助我了解原因,所以我决定尝试一下,只是为了教育自己。 This is my attempt so far,关于Github Gist。我在下面写了一些片段。
在await
函数中:
function await (promise) {
/* PromiseState declared here */
var self = {
result: null,
state: PromiseState.pending
};
function onPromiseUpdate(context, newState) {
return function (value) {
console.log("Promise Updated!");
context.result = value;
context.state = newState;
}
}
console.log("awaiting");
// this never shows the Promise to be pending (using example below)
console.log(promise);
promise
.then(onPromiseUpdate(self, PromiseState.resolved)) // this is never called
.catch(onPromiseUpdate(self, PromiseState.rejected));
// Shouldn't this not block the app if it's inside a Promise?
while (self.state == PromiseState.pending) ;
console.log("delegating");
/* just returning the value here */
}
示例:
// is there another way to pass 'await' without a parameter?
unstableFunc = async(function (await) {
console.log("running unstable");
if(Math.random() > 0.5) return Math.random() * 15 + 5;
else throw "fail";
});
expensiveFunc = async(function (await, x, y) {
result = await(unstableFunc())
for (var i = y * 8; i >= 0; i--) {
result *= i ** y / x;
console.log(result);
}
return result;
});
window.addEventListener('load', function () {
console.log("about to do something expensive");
// 'expensiveFunc' returns a Promise. Why does this block the webpage?
expensiveFunc(10, 2).then(function (val) {
console.log("Result: " + val.toString());
});
console.log("called expensive function");
});
运行此操作时,浏览器无法完成加载。这与我设置的循环有关,以检查正在解决的Promise的状态,但这不是我的问题的焦点。我想知道的是为什么then
或catch
回调都没有被调用。记录时,控制台永远不会记录待处理的Promise,而且我一直认为then
和catch
如果未来未处于待处理状态,会立即执行回调。在这种情况下,为什么不是这样呢?
答案 0 :(得分:1)
到达/执行此代码行的那一刻:
while (self.state == PromiseState.pending) ;
您的脚本将永久被阻止(或者直到选项卡崩溃或浏览器将其终止)。当该循环正在运行时,回调不能运行(也不能运行任何其他),因此您的promise状态永远不会更改为pending,从而导致无限循环。承诺涉及不会改变上述任何一项。