【发布时间】:2016-06-10 18:13:54
【问题描述】:
C#/Dart 的 async/await 功能有点宠坏了我。我注意到 ES7 提出了类似语法的提议,并且 there is a library 将该功能添加到 Node.JS 应用程序中。
这个库在浏览器中不起作用。我想通过尝试编写自己的迷你解决方案可能会帮助我了解原因,所以我决定尝试一下,只是为了教育自己。 This is my attempt so far,在 Github Gist 上。我在下面包含了 sn-ps。
在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 会在未来未未决的情况下立即执行它们的回调。为什么在这种情况下不是这样?
【问题讨论】:
-
哇,你为什么要使用无限循环来检查承诺是否已经实现?
-
@HenriqueBarcelos 我为自己感到羞耻,因为您可能很害怕。在我正在尝试做的事情的范围内,有没有更好的方法来检查?
-
不定式循环将阻塞事件循环,防止任何事件或回调无限期触发。使用断点或 console.log。
-
@WillemD'Haeseleer 呵呵。 Promise 中的所有内容不是异步执行的吗?我认为 promise 中的所有内容都不会阻塞主线程
-
不,promise 与使同步事物异步无关。如果它阻塞了事件循环,它就会阻塞它,不管它在哪里当它运行时。
标签: javascript node.js asynchronous promise async-await