koa2异步返回值解决方案(ctx.body无效)

首先我在哪里出的问题,在写百度人脸搜索库的时候我使用node的request模块请求数据,数据请求成功代码如下

var https=require("https");
var request = require('request')

var qs = require('querystring');  
var baiduconfig = require('../config/baidu')



/**
 * setContent to baidu house
 *
 * @param picurl picture of url 
 * @param picname picture of file name (you can understand it as unique code for pic)
 * @AUTHOR boker
 * @DATE 2020-05-07
 */
function addBaidu (picurl, picname,suc) {
    
    
    var content = qs.stringify(baiduconfig);  
    var options = {  
        hostname: 'aip.baidubce.com',  
        path: '/oauth/2.0/token?' + content,  
        method: 'GET'  
    };  
    var req =  https.request(options, function (res) {  
        res.setEncoding('utf8');  
        res.on('data', function (chunk) {          
            let _session = JSON.parse(chunk).access_token
            let picoption = {
                image:'',
                image_type:'URL',
                group_id:'face',
                user_id:''
            } 
            picoption.image = picurl
            picoption.user_id = picname
            // console.log(picoption)
            // console.log(_session)
             request({
                url: 'https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token='+_session,
                method: "POST",
                json: true,
                headers: {
                  "content-type": "application/json",
                },
                body: picoption
                },function(error, response, body) {
                if (!error && response.statusCode == 200) {
                    suc(body)
                }
                else {
                    tempreturn = '404'
                }
            });
        });  
    });  
    req.on('error', function (e) {  
        console.log('problem with request: ' + e.message);  
    });  
    req.end();  
    return asd
}
 
module.exports = {
    addBaidu
}

在没加promise函数之前不能在request中通过ctx.body返回给前台数据,百思不得其解的我进行了无数的测试,我发现除了ctx.body其余的操作都可以进行,通过思考过后我找到了问题的原因请求异步所致

查找Node学习指南一书指出,node通过EventEmitter注册的事件都是抛给事件队列去通过事件注册的方法异步处理的,其中文件读写,HTTP请求,SQL等默认都是非阻塞异步I/O,而ctx.body作为返回值,在异步没有执行结束时被执行,会造成很多后果,所以我们在异步request对象内部ctx.body事件驱动不能解析(如果解析了下面的事件执行失去意义)

为了解决这个问题,首先我想到的是同步写法,发现很多同步中间件都被废弃了,那么取而代之一定就是我们经常用的async/await和promise了,这种非同步的同步写法,具体我是这样解决的(代码)

//newSet.js
var https = require("https");
var request = require('request')

var qs = require('querystring');
var baiduconfig = require('../config/baidu')



/**
 * setContent to baidu house
 *
 * @param picurl picture of url 
 * @param picname picture of file name (you can understand it as unique code for pic)
 * @AUTHOR boker
 * @DATE 2020-05-07
 */
function addBaidu(picurl, picname) {
    var content = qs.stringify(baiduconfig);
    var options = {
        hostname: 'aip.baidubce.com',
        path: '/oauth/2.0/token?' + content,
        method: 'GET'
    };

    return new Promise((resolve, reject) => {
        var req = https.request(options, function (res) {
            res.setEncoding('utf8');
            res.on('data', function (chunk) {
                let _session = JSON.parse(chunk).access_token
                let picoption = {
                    image: '',
                    image_type: 'URL',
                    group_id: 'face',
                    user_id: ''
                }
                picoption.image = picurl
                picoption.user_id = picname
                // console.log(picoption)
                // console.log(_session)
                request({
                    url: 'https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=' + _session,
                    method: "POST",
                    json: true,
                    headers: {
                        "content-type": "application/json",
                    },
                    body: picoption
                }, function (error, response, body) {
                    if (!error && response.statusCode == 200) {
                        resolve(body)
                    }
                    else {

                    }
                });
            });
        })
        req.on('error', function (e) {
            console.log('problem with request: ' + e.message);
        });
        req.end();
    })
}

module.exports = addBaidu

//dao_doAdd.js
var searchHelp = require('.././../databs/searchHelp')
var addBaidu = require('../../baidu/api/newset')


// var path = require('path')
//数据试测试用的
async function dao_doAdd(ctx) {
    ctx.set('Access-Control-Allow-Origin', '*');
    ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
    ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
    let mid = ctx.request.body;
    // let search = new searchHelp({ posX: mid.pox, posY: mid.poy, name: mid.name, picSrc: ctx.request.files.file.path })
    let search = new searchHelp({ picSrc: ctx.request.files.file.path })
    let resulet = search.save()


   let results = await addBaidu('http://47.93.205.58/www/pic/upload_357d3f1638d1b6cc3a8f408476e5ff84.jpg', '23512031c716791e8b409c083e34864e',ctx)
   ctx.body ={data: results };

}
module.exports = dao_doAdd
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值