用async/await多个返回值的方法,可以直接接收吗?比如 var value = request(url);
发布于 7 年前 作者 tomoya92 7812 次浏览 来自 问答

RT

回调写法是

request(url, function(err, resp, body){
//TODO
})

如果用nodejs7里的async/await可以把这个转换成下面这样的写法吗?

var value = request(url);
//TODO

求解!

22 回复
var requestAction = function (url) {
    return new Promise(function (resolve, reject) {
        request({url: url}, function (error, response, body) {
            if (error) return reject(error);

            resolve(body);
        })
    });
};

var value = await requestAction(url); // 这里调用要在 async 函数里

@imhered 感谢,明白了,还是要用Promise包装一下

兄台是不是想要这样的形式:

co(function*(co_next){
  let [err,res,body] = yield  request(url,co_next);
  //......
})()

@liygheart 是的,必须要用Promise包装

@yyrdl 这个更简单。。赞

go里就可以用多个对象来接收多个返回值的,用着实在方便,用co在nodejs里也可以这样实现,大赞

@liygheart 基于 zco 写的,自己开发的一个模块,还有其他特别有用的功能,亲可以试用一下,https://github.com/yyrdl/zco :) ,求star^ -^

@yyrdl 好东西,已star

@liygheart 谢谢 ,欢迎pr :)

@imhered 有个问题,如果用这种方法,调用后会卡在终端里,是怎么回事呢?

我封装了一个mysql的query方法,大大帮忙看看

var db = {};
var mysql = require('mysql');
var config = require('./config.js');
var pool = mysql.createPool({
  connectionLimit: 10,
  host: config.db.host,
  user: config.db.user,
  password: config.db.password,
  database: config.db.database
});

db.query = function (sql) {
  if (!sql) return undefined;
  return new Promise(function (resolve, reject) {
    pool.query(sql, function (error, rows, fields) {
      if (error) {
        reject(error);
      } else {
        resolve(rows);
      }
    });
  });
};

module.exports = db;

return undefined 改成 return Promise.resolve(undefined) 如果想返回错误的话可以用 return Promise.reject(undefined)

@imhered 改过来了,程序结束了,还是卡在终端里。。

yield 后面不是 promise 或者是同步方法的话有什么意义? 不懂 co 加 Generator 到底哪里比 async await 简单。

@jokerapi Promise是相对于callback的一个进化,但不是最优方案,yield的语义为转移代码运行权限,可理解为让出CPU。 就拿楼主的mysql.query举个例子,为了使用async await 需要先包装成promise, 这算是语法限制吧,但是基于generator开发的corountine模块可以克服这些不必要的麻烦。 楼主的quey 模块可改写成:

var mysql = require('mysql');
var config = require('./config.js');
var pool = mysql.createPool({
  connectionLimit: 10,
  host: config.db.host,
  user: config.db.user,
  password: config.db.password,
  database: config.db.database
});

module.exports = pool;

外部使用:

const co = require("zco");
const mysql_db = require("./mysql_db");//即上面的代码

//假设要在db之上实现一个根据用户名查手机通讯录的操作,并假设需要俩次查库操作

const findPhoneListByUser=function(user){
   return co(function*(co_next){
      let sql1= "";
	  let [err,rows,fileds] = yield mysql_db.query(sql1,co_next);
	  //.......
	  let sql1= "";
	  let [err2,rows2,fileds2] = yield mysql_db.query(sql2,co_next);
	  //.....
	  return phone_list;
   });
}

直观的感受是更直接,更简洁

@liygheart 程序结束了? 卡在终端里? 什么意思?是进程没结束么?

@imhered 对,就是程序结束了,但终端里还没有结束,啥也不输出了,就像是启动了一个服务在那监听一样,只能按 ctrl+c才能关掉

@liygheart 是这样的啊。 调用 process.exit() 才退出

@imhered 用Permise土封装的方法,被调用都会停在终端里吗?它不会默认退出的?在没有用Permise封装的方法之前,调用了之后,它是自动退出的

@liygheart 好像是这样的。 我没仔细研究过。 如果要退出的话,执行一下 process.exit()

@imhered 好的,谢谢

@yyrdl 用zco总是返回 { [Function: zco_core_future] __suspend__: [Function], __ctx__: [Function] }

就算我 return ‘1111’ 也是返回那个东西,请问这个是什么情况?

const demo = function (name) {
  return co(function* () {
    return '1111';
  })
}

// 调用 

var value = demo('hello');
console.log(value); //{ [Function: zco_core_future] __suspend__: [Function], __ctx__: [Function] }

@liygheart 这个是用法问题,如果是直接调用的话是这样用的:

 demo("hello")((err,result)=>{
    if(err){
	  console.log(err);
	}else{
	  console.log(result);//"1111"
	}
 })

或者 :

 co.brief(function*(){
    let value = yield demo("hello");
	console.log(value);//'1111'
 })()

还有你那个终端不退出的问题应该是event_loop还在运行,参考:https://github.com/mysqljs/mysql#closing-all-the-connections-in-a-pool

@yyrdl 用了co.brief 就好了

终端不退出问题也解决了,谢谢 :)

回到顶部