nodejs中异步函数的回调中使用ctx.body接口获取不到返回值

在用eggjs做后台服务端时,需要去调微信的接口获取openid等信息,然后返回一个结果给前端。

一开始是这么写的

// 登录的controller
async index(ctx) {
	// 接受前端传来的code等信息

	request(`https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${code}&grant_type=authorization_code`,function (error, response, body) {
		if(error) { //请求异常时,返回错误信息
    	return reject(error);
    	} else {
    		const bodyJson = JSON.parse(body);
       	 	const { session_key, openid } = bodyJson;
       	 	// ... 处理数据,保存用户信息等操作
			console.log(bodyJson)
			ctx.body = {
				code: 0,
				msg: '登录成功'
			}
    	}
	}
}

在测试的时候发现,接口调用后始终没有数据返回,但是在controller中输出bodyJson也一直有值,代表回调函数确实执行了。
查找资料后,有大佬指出是洋葱圈模型没有理解,才会写出这样的代码(还是没怎么懂)。
我的理解是整个代码顺序执行,执行到request是异步的,未触发回调函数(未等待函数执行完成)就执行到controller的末尾,由于没有 ctx.body,就直接返回响应,所以前端是404,接收不到回调函数的返回。之后触发了回调函数所以输出了bodyJson的值,但此时的ctx.body返回已经没有用了。所以正确的思路是等待request执行完拿到结果后再ctx.body返回结果。

修改后的写法

	const requestPromise = new Promise((resolve, reject) => { // 需要封装成 Promise,等待执行完返回请求。回调中无法 ctx.body 返回响应
      // 获取 session_key 和 openid,并更新用户
      request(`https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${code}&grant_type=authorization_code`, async function (error, response, body) {
        if(error) { //请求异常时,返回错误信息
          return reject(error);
        } else {
          const bodyJson = JSON.parse(body);
          const { session_key, openid } = bodyJson;    
          /**
		   *	处理,保存数据等操作
		   */ 
          return resolve({
            userId,
            openId: openid,
            avatar: userInfo.avatarUrl,
            city: userInfo.city,
            gender: userInfo.gender,
            nickname: userInfo.nickName,
            province: userInfo.province,
          })
        }
      });
    })

    const result = await requestPromise;
	// 最后接口返回数据
	ctx.body = {
		code: 0,
		msg: 'ok',
	}

你可能感兴趣的:(nodejs中异步函数的回调中使用ctx.body接口获取不到返回值)