mongoose异步操作造成ctx.body不正常,求解决
发布于 2 年前 作者 bringtree 2661 次浏览 来自 问答
router.post('/user/api/add', async (ctx,next) => {
  var username = ctx.session.current_user.username;
  var oldAccount = "";
  var account = {
    thing: ctx.request.body.thing,
    date: ctx.request.body.date,
    status: ctx.request.body.status,
    money: ctx.request.body.money
  };
  var resBody={};
  await UserModel.findByUsername(username, function (err, doc) {
    if (doc) {
      oldAccount = doc.accounts;
      oldAccount.push(account);
    } else {
      console.log(err);
      resBody = {
        type: "fail",
        message: "please check out your login status or input"
      }
    }
    return resBody;
  })
   UserModel.addAccount(username, oldAccount, function (err, doc) {
    if (doc) {
      resBody = {
        type: "success",
        message: "input success"
      }
      console.log(resBody)

    }
    else {
      console.log(err);
      resBody = {
        type: "fail",
        message: "please check out your login status or input"
      }
    }
  });
  ctx.body = resBody
  //ctx.body="上面数据库操作是能进行 但是由于异步问题   我实在无法解决 ctx.body ={}";

});```
下面是上面那2个函数

UserSchema.statics.findByUsername = function (username, cb) { return this.findOne({username: username}, cb); }

UserSchema.statics.addAccount = function(username,account,cb){ return this.findOneAndUpdate({username:username},{“accounts”:account},cb); }```

7 回复

之前 采用过 function*(next){ yield XX.exec(); this.body = abc; } 但是 这里我用了 也没用

用bluebird 的Promise.promisify 提示 mongoose this.parse 错误

说下我自己的用mongoose的方案。

  1. 配置数据库连接需要配置:

    mongoose.Promise = global.Promise;

  2. model层写方法:

    ProjectSchema.methods.apis = async function () {
    	const projectId = this._id;
    	const apis = await Api.find({project: projectId}).exec();
    	return apis;
    };
    

然后你在

	await UserModel.findByUsername(username, function (err, doc) {
		if (doc) {
		  oldAccount = doc.accounts;
		  oldAccount.push(account);
		} else {
		  console.log(err);
		  resBody = {
			type: "fail",
			message: "please check out your login status or input"
		  }
		}
		return resBody;
  	})

用了await又用callback,显然没必要。

@nullcc 我调试了程序 运行时这样子的 他先route运行完(这时候如果没有ctx.body 就默认返回404,如果有就直接丢个空,因为这时候外面 2个mongoose操作还没执行。) 再去执行外面 2个mongoose的函数(这时候在回调中加ctx.body也没用了)。。我对无法await理解,我认为await 是 可以阻塞这个函数 等待 mongoose 操作完毕的。 我想问下 如果我现在这个要如何改?

Query#exec([operation], [callback])

Executes the query

Parameters:

[operation] <String, Function>
[callback] <Function> optional params depend on the function being called
Returns:

<Promise>

正常情况下,await命令后面是一个 Promise 对象

UserSchema.statics.findByUsername = function (username) {
return this.findOne({username: username}).exec();
}

UserSchema.statics.addAccount = function(username,account){
return this.findOneAndUpdate({username:username},{“accounts”:account}).exec();
}
 var result1 = await UserModel.findByUsername(username);
 //
 if (result1) {
    //todo 做你的操作
    } else {
      resBody = {
        type: "fail",
        message: "please check out your login status or input"
      }
	  	 ctx.body = resBody
       return
    }
  })
 var result2 = await UserModel.addAccount(username, oldAccount);
	 if (result2) {
    //todo 做你的操作
    } else {
		resBody = {
		  type: "fail",
		  message: "please check out your login status or input"
		}
    }
	 ctx.body = resBody
    return
  })

@jiangli373 谢谢了, 但是 我还是搞不懂 await 对generator 到底是做了 什么 有比较 好的文章吗 或 介绍吗

回到顶部