Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 异步/等待隐式返回承诺?_Javascript_Node.js_Async Await_Ecmascript Next - Fatal编程技术网

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
和at
yield 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
和at
yield 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
是一个函数