在以下情况下如何正确使用 async-await?

问题描述

我正在为异步等待块而苦苦挣扎。我查看了网上的多种资源,但我无法理解我在这里做错了什么:

app.post('/api/my-api',async (req,res,next) => {
try {
    filecontent = req.files.userFile.data.toString('utf8')
    console.log("decoded file : ",filecontent);
    let encoded_file = new Buffer(filecontent).toString('base64');
    var apiClass = new RPC("http://localhost:1006","my-api");

    //the asynchronous function :
    const answ = await apiMethod.call("api",[{"file" : encoded_file,"fileName":req.files.userFile.name}],res.json);

    //the code I'd like to execute only after the prevIoUs function has finished :
    console.log("answer : ",answ);
    console.log("answering...");
    res.json(answ);
} catch (err) {
    console.log(err);
}

显然我的 console.log 是在 await 行完成之前执行的。我可以判断,因为异步函数中也有 console.log(),而且我的 res.json 在我收到 answ 之前发送。

如何确保异步函数在其余代码之前完成?

编辑:这里是 apiMethod.call 函数

call(id,params) {
    let options = {
        url: this.url,method: "post",headers:
        { 
         "content-type": "text/plain"
        },body: JSON.stringify( {"jsonrpc": "2.0","id": id,"method": this.procedure,"params": params })
    };
    console.log(options);
    request(options,(error,response,body) => {
        if (error) {
            console.error('An error has occurred: ',error);
        } else {
            console.log('Post successful: response: ',body);
        }
    });
}

解决方法

问题在 call 函数中。由于它具有异步代码(request 调用),因此应将其包装在应从 request 的回调函数解析的 promise 中。

将调用函数更新为如下所示的内容应该会有所帮助:

function call(id,params) {
  return new Promise((resolve,reject) => {
    let options = {
      url: this.url,method: "post",headers: {
        "content-type": "text/plain",},body: JSON.stringify({
        jsonrpc: "2.0",id: id,method: this.procedure,params: params,}),};
    console.log(options);
    request(options,(error,response,body) => {
      if (error) {
        console.error("An error has occurred: ",error);
        reject(error);
      } else {
        console.log("Post successful: response: ",body);
        resolve(body);
      }
    });
  })
}