Javascript 异步/等待隐式返回承诺?
我了解到,由Javascript 异步/等待隐式返回承诺?,javascript,node.js,async-await,ecmascript-next,Javascript,Node.js,Async Await,Ecmascript Next,我了解到,由async关键字标记的异步函数隐式返回一个承诺: async function getVal(){ return await doSomethingAync(); } var ret = getVal(); console.log(ret); 但是这是不一致的…假设doSomethingAsync()返回一个承诺,而await关键字将返回承诺中的值,而不是承诺itsef,那么我的getVal函数应该返回该值,而不是隐式承诺 那么到底是什么情况呢?用async关键字标记的函数是否
async
关键字标记的异步函数隐式返回一个承诺:
async function getVal(){
return await doSomethingAync();
}
var ret = getVal();
console.log(ret);
但是这是不一致的…假设doSomethingAsync()
返回一个承诺,而await关键字将返回承诺中的值,而不是承诺itsef,那么我的getVal函数应该返回该值,而不是隐式承诺
那么到底是什么情况呢?用async关键字标记的函数是否隐式返回承诺,或者我们是否控制它们返回的内容
也许,如果我们没有明确地返回某个东西,那么他们就会隐式地返回一个承诺
更清楚地说,以上和以下两者之间存在差异
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
在我的概要中,这种行为确实与传统的返回语句不一致。当从async
函数显式返回非承诺值时,它将强制将其包装为承诺。
我对它没有太大的问题,但它确实违背了正常的JS。返回值始终是一个承诺。如果没有显式返回承诺,则返回的值将自动包装在承诺中
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));
即使没有回报也一样!(Promise{undefined}
返回)
即使有等待
,也是一样的
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));
承诺自动展开,因此如果您确实从async
函数中返回值承诺,您将收到值承诺(而不是值承诺)
在我的简介中,这种行为确实与传统的行为不一致 返回语句。当您显式返回 来自异步函数的非承诺值,它将强制在 答应我。我没有什么大问题,但它确实违背了正常规律 JS ES6的函数返回的值与
返回的值不完全相同。这些函数称为生成器
function* foo() {
return 'test';
}
// Logs an object.
console.log(foo());
// Logs 'test'.
console.log(foo().next().value);
回报价值永远是一种承诺。如果没有显式返回承诺,则返回的值将自动包装在承诺中
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));
即使没有回报也一样!(Promise{undefined}
返回)
即使有等待
,也是一样的
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));
承诺自动展开,因此如果您确实从async
函数中返回值承诺,您将收到值承诺(而不是值承诺)
在我的简介中,这种行为确实与传统的行为不一致
返回语句。当您显式返回
来自异步函数的非承诺值,它将强制在
答应我。我没有什么大问题,但它确实违背了正常规律
JS
ES6的函数返回的值与返回的值不完全相同。这些函数称为生成器
function* foo() {
return 'test';
}
// Logs an object.
console.log(foo());
// Logs 'test'.
console.log(foo().next().value);
async不返回承诺,await关键字等待承诺的解析。async是一个增强的生成器函数,wait的工作方式有点像yield
我认为语法(我不是100%确定)是
异步函数*getVal(){…}
ES2016生成器函数的工作方式有点像这样。我已经做了一个数据库处理程序,它是基于您这样编写的冗长程序之上的
db.exec(function*(connection) {
if (params.passwd1 === '') {
let sql = 'UPDATE People SET UserName = @username WHERE ClinicianID = @clinicianid';
let request = connection.request(sql);
request.addParameter('username',db.TYPES.VarChar,params.username);
request.addParameter('clinicianid',db.TYPES.Int,uid);
yield connection.execSql();
} else {
if (!/^\S{4,}$/.test(params.passwd1)) {
response.end(JSON.stringify(
{status: false, passwd1: false,passwd2: true}
));
return;
}
let request = connection.request('SetPassword');
request.addParameter('userID',db.TYPES.Int,uid);
request.addParameter('username',db.TYPES.NVarChar,params.username);
request.addParameter('password',db.TYPES.VarChar,params.passwd1);
yield connection.callProcedure();
}
response.end(JSON.stringify({status: true}));
}).catch(err => {
logger('database',err.message);
response.end(JSON.stringify({status: false,passwd1: false,passwd2: false}));
});
注意我是如何像普通同步程序一样编程的,尤其是在
yield connection.execSql
和atyield connection.callProcedure
db.exec函数是一个非常典型的基于Promise的生成器
exec(generator) {
var self = this;
var it;
return new Promise((accept,reject) => {
var myConnection;
var onResult = lastPromiseResult => {
var obj = it.next(lastPromiseResult);
if (!obj.done) {
obj.value.then(onResult,reject);
} else {
if (myConnection) {
myConnection.release();
}
accept(obj.value);
}
};
self._connection().then(connection => {
myConnection = connection;
it = generator(connection); //This passes it into the generator
onResult(); //starts the generator
}).catch(error => {
reject(error);
});
});
}
async不返回承诺,await关键字等待承诺的解析。async是一个增强的生成器函数,wait的工作方式有点像yield
我认为语法(我不是100%确定)是
异步函数*getVal(){…}
ES2016生成器函数的工作方式有点像这样。我已经做了一个数据库处理程序,它是基于您这样编写的冗长程序之上的
db.exec(function*(connection) {
if (params.passwd1 === '') {
let sql = 'UPDATE People SET UserName = @username WHERE ClinicianID = @clinicianid';
let request = connection.request(sql);
request.addParameter('username',db.TYPES.VarChar,params.username);
request.addParameter('clinicianid',db.TYPES.Int,uid);
yield connection.execSql();
} else {
if (!/^\S{4,}$/.test(params.passwd1)) {
response.end(JSON.stringify(
{status: false, passwd1: false,passwd2: true}
));
return;
}
let request = connection.request('SetPassword');
request.addParameter('userID',db.TYPES.Int,uid);
request.addParameter('username',db.TYPES.NVarChar,params.username);
request.addParameter('password',db.TYPES.VarChar,params.passwd1);
yield connection.callProcedure();
}
response.end(JSON.stringify({status: true}));
}).catch(err => {
logger('database',err.message);
response.end(JSON.stringify({status: false,passwd1: false,passwd2: false}));
});
注意我是如何像普通同步程序一样编程的,尤其是在
yield connection.execSql
和atyield connection.callProcedure
db.exec函数是一个非常典型的基于Promise的生成器
exec(generator) {
var self = this;
var it;
return new Promise((accept,reject) => {
var myConnection;
var onResult = lastPromiseResult => {
var obj = it.next(lastPromiseResult);
if (!obj.done) {
obj.value.then(onResult,reject);
} else {
if (myConnection) {
myConnection.release();
}
accept(obj.value);
}
};
self._connection().then(connection => {
myConnection = connection;
it = generator(connection); //This passes it into the generator
onResult(); //starts the generator
}).catch(error => {
reject(error);
});
});
}
我查看了规范,发现了以下信息。简短的版本是,一个异步函数
与一个生成Promise
s的生成器相连接。因此,是的,异步函数返回承诺
根据调查,以下情况属实:
async function <name>?<argumentlist><body>
我查看了规范,发现了以下信息。简短的版本是,一个异步函数
与一个生成Promise
s的生成器相连接。因此,是的,异步函数返回承诺
根据调查,以下情况属实:
async function <name>?<argumentlist><body>
调用函数时,只需在函数之前添加wait:
var ret = await getVal();
console.log(ret);
调用函数时,只需在函数之前添加wait:
var ret = await getVal();
console.log(ret);
您的问题是:如果我创建了一个异步
函数,它是否应该返回承诺回答:只要做你想做的事情,Javascript就会帮你解决
假设doSomethingAsync
是一个返回承诺的函数。然后
async function getVal(){
return await doSomethingAsync();
}
完全一样
async function getVal(){
return doSomethingAsync();
}
你可能在想“WTF,这些怎么可能是一样的?”你是对的。async
将神奇地在必要时用承诺包装一个值
更奇怪的是,可以编写doSomethingAsync
来有时返回承诺,有时不返回承诺。尽管如此,这两个函数还是完全相同的,因为等待
也是魔法。如果有必要,它将打开承诺,但对非承诺的事情不会产生任何影响。您的问题是:如果我创建了一个异步
函数,它是否应该返回承诺回答:只要做你想做的事情,Javascript就会帮你解决
假设doSomethingAsync
是一个函数