如何使用Node.js中的promise将异步函数转换为同步函数?

时间:2017-08-22 15:44:56

标签: node.js api

我已经根据建议更改了我的代码我仍然无法访问该值并且无法读取未定义的属性“0”的错误。第三个函数无法访问task_id,因为它未创建:< / p>

 app.post('/api/add_task',function(req,res,error){
  var sql = "INSERT INTO `campus_ambassador`.`tasks` ( `task_type`, `task_name`, `details`, `social_media_handles`, `media`, `created_date`, `updated_date`) VALUES ('offline', 'golfed', 'ssss', '#soccer', 'sdfsd', '2012-12-26 00:00:00', '2012-12-26 00:00:00');"
  var sql1 = "select task_id from tasks where task_name='golfed'";
  var sql2 = "INSERT INTO `campus_ambassador`.`task_level` (`task_id`, `level_id`, `updated_on`, `created_on`) VALUES ("+"'"+res1[0].task_id+"'"+", '3', '2012-12-26 00:00:00', '2012-12-26 00:00:00')";
  var res1=''

  async.waterfall([
  function(callback){  
      db.select(sql,function(err){
          console.log("made the task");
          callback(null);

          })

      },

      function(callback){
  db.select(sql1,function(err,data){
                res1 = data;
                console.log(res1);
                console.log(res1[0].task_id);
                console.log("got the task id of the created task")
                res.end();
                 callback(null,data);   
                    })
          },
    function(callback){
              db.select(sql2,function(err){
              console.log(res1[0].task_id)
            console.log("updated the task level table")
            callback(null);
          })
       }

 ],
    function(err,results){
        console.log(JSON.stringify(results));
    })
})

1 个答案:

答案 0 :(得分:2)

这实际上取决于一些事情。你正在使用什么版本的节点,以及你的lib支持db。

将回调转为承诺

如果您的db默认情况下不支持promise,则必须自己执行,如下所示:

var dbSelectPromise = function(db, sql) {
    return new Promise(function(resolve, reject) {
        db.select(sql, function(err, data) {
            if (err) {
                reject(err)
            } else {
                resolve(data)
            }
        })
    })
}

使用承诺

一旦你将它作为一个承诺(要么你做了它,要么它是你的数据库本机)你可以像这样使用它

dbSelectPromise(db, sql)
.then(function(fristResult) {
    return dbSelectPromise(db, sql1)
})
.then(function(secondResult) {
    return dbSelectPromise(db, sql2)
})
.then(function(thirdResult) {
    // And so on...
})
.catch(function(err) {
    // Here you can handle errors for all of them
})

使用async / await

如果你的节点版本是7.6或更高,你可以做得更好。首先改变承诺功能:

var dbSelectPromise(db, sql) = async function {
    return new Promise(function(resolve, reject) {
        db.select(sql, function(err, data) {
            if (err) {
                reject(err)
            } else {
                resolve(data)
            }
        })
    })
}

然后您可以像使用同步代码一样使用它:

var fristResult = await dbSelectPromise(db, sql)
var secontResult = await dbSelectPromise(db, sql1)
var thirdResult = await dbSelectPromise(db, sql2)

修改 要将结果保存到倍数&#34;然后&#34;您可以将结果保存在外部范围内,如下所示:

var frist, second, third
dbSelectPromise(db, sql)
.then(function(fristResult) {
    frist = fristResult
    return dbSelectPromise(db, sql1)
})
.then(function(secondResult) {
    second = secondResult
    return dbSelectPromise(db, sql2)
})
.then(function(thirdResult) {
    third = thirdResult
    // And so on...
})
.catch(function(err) {
    // Here you can handle errors for all of them
})