Ale*_*lls 85 javascript node.js async-await ecmascript-next
我读到由async
关键字标记的异步函数隐式返回一个promise:
async function getVal(){
return await doSomethingAync();
}
var ret = getVal();
console.log(ret);
Run Code Online (Sandbox Code Playgroud)
但这不是连贯的...假设doSomethingAsync()
返回一个promise,而await关键字将返回promise中的值,而不是promise itsef,那么我的getVal函数应返回该值,而不是隐式promise.
那究竟是什么情况呢?由async关键字标记的函数是否隐式返回promises,还是我们控制它们返回的内容?
也许如果我们没有明确地回报某些东西,那么它们会隐含地回报一个承诺......?
更清楚的是,上述和之间存在差异
function doSomethingAync(charlie) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(charlie || 'yikes');
}, 100);
})
}
async function getVal(){
var val = await doSomethingAync(); // val is not a promise
console.log(val); // logs 'yikes' or whatever
return val; // but this returns a promise
}
var ret = getVal();
console.log(ret); //logs a promise
Run Code Online (Sandbox Code Playgroud)
在我的概要中,行为确实与传统的return语句不一致.看来,当您从async
函数中显式返回非promise值时,它会强制将其包装在promise中.我没有一个大问题,但它确实违反了普通的JS.
Nat*_*all 102
返回值始终是一个承诺.如果您未明确返回承诺,则您返回的值将自动包含在承诺中.
async function increment(num) {
return num + 1;
}
// Even though you returned a number, the value is
// automatically wrapped in a promise, so we call
// `then` on it to access the returned value.
//
// Logs: 4
increment(3).then(num => console.log(num));
Run Code Online (Sandbox Code Playgroud)
同样的事情,即使有一个await
.
function defer(callback) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(callback());
}, 1000);
});
}
async function incrementTwice(num) {
const numPlus1 = await defer(() => num + 1);
return numPlus1 + 1;
}
// Logs: 5
incrementTwice(3).then(num => console.log(num));
Run Code Online (Sandbox Code Playgroud)
Promises自动解包,所以如果你确实从async
函数中返回一个值的promise ,你将收到一个值的承诺(不是对值的承诺).
function defer(callback) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(callback());
}, 1000);
});
}
async function increment(num) {
// It doesn't matter whether you put an `await` here.
return defer(() => num + 1);
}
// Logs: 4
increment(3).then(num => console.log(num));
Run Code Online (Sandbox Code Playgroud)
在我的概要中,行为确实与传统的return语句不一致.看来,当您从异步函数显式返回非promise值时,它会强制将其包装在promise中.我没有一个大问题,但它确实违反了普通的JS.
ES6的功能不会返回与...完全相同的值return
.这些函数称为生成器.
function* foo() {
return 'test';
}
// Logs an object.
console.log(foo());
// Logs 'test'.
console.log(foo().next().value);
Run Code Online (Sandbox Code Playgroud)
Jon*_*ell 19
我查看了规范并找到了以下信息.简短的版本是一个async function
产生Promise
s 的发电机的desugars .所以,是的,异步函数返回promises.
根据tc39规范,以下情况属实:
async function <name>?<argumentlist><body>
Run Code Online (Sandbox Code Playgroud)
Desugars:
function <name>?<argumentlist>{ return spawn(function*() <body>, this); }
Run Code Online (Sandbox Code Playgroud)
其中spawn
"是对以下算法的调用":
function spawn(genF, self) {
return new Promise(function(resolve, reject) {
var gen = genF.call(self);
function step(nextF) {
var next;
try {
next = nextF();
} catch(e) {
// finished with failure, reject the promise
reject(e);
return;
}
if(next.done) {
// finished with success, resolve the promise
resolve(next.value);
return;
}
// not finished, chain off the yielded promise and `step` again
Promise.resolve(next.value).then(function(v) {
step(function() { return gen.next(v); });
}, function(e) {
step(function() { return gen.throw(e); });
});
}
step(function() { return gen.next(undefined); });
});
}
Run Code Online (Sandbox Code Playgroud)
你的问题是:如果我创建一个async
函数,它是否应该返回一个承诺?回答:做任何你想做的事,Javascript 会为你修复它。
假设doSomethingAsync
是一个返回承诺的函数。然后
async function getVal(){
return await doSomethingAsync();
}
Run Code Online (Sandbox Code Playgroud)
完全一样
async function getVal(){
return doSomethingAsync();
}
Run Code Online (Sandbox Code Playgroud)
你可能在想“ WTF,这些怎么可能一样? ”你是对的。该async
会神奇地包裹并承诺值,如果必要的。
更奇怪的是,doSomethingAsync
可以写成有时返回承诺,有时不返回承诺。仍然两个功能完全相同,因为await
也是magic。如有必要,它会打开一个 Promise ,但它不会影响非 Promise 的东西。