新人关于node异步同步的问题
发布于 1 天前 作者 enternull 179 次浏览 来自 问答

新人写了个demo 大概功能就是获取一张图片然后合成上传腾讯云 但是测试发现很多失败的请求 169505E3AABE23ECEC7043749B7AF7E2.jpg 大致测试结果只有21个成功了 估计是node异步之类Promise间的问题 想问问到底是哪里出了错 导致整个请求可能出错

const fs = require('fs')
const Canvas = require('canvas')
const path = require('path')
const cos = require('../../utils/os')
const config = require('../../config/default')
const request = require('request')
let response = require('../../utils/defaultResponse')

function processingPicture(context, next) {
    return new Promise((resolve, reject) => {
        let avatarUrl = context.request.query.avatarUrl
        let luckStatus = context.request.query.luckStatus
        let nickName = context.request.query.nickName
        if (!avatarUrl || !luckStatus || !nickName || luckStatus > 16) {
            response.Success = false
            response.ErrorCode = 101
            response.ErrorMessage = '请传入正确参数'
            context.body = response
            return
        }
        let Image = Canvas.Image
        let defaultConfig = {
            width: 750,
            height: 1206
        }
        let canvas = new Canvas(defaultConfig.width, defaultConfig.height)
        let ctx = canvas.getContext('2d')
        let img = new Image()
        let avatar = new Image()
        img.src = fs.readFileSync(path.resolve(__dirname, luckStatus.png))
        ctx.drawImage(img, 0, 0, defaultConfig.width, defaultConfig.height)
        ctx.font = '32px Impact'
        ctx.fillStyle = '#1a5e7e'
        ctx.fillText(nickName, 205, 130)
        requestAsync({
            url: avatarUrl,
            encoding: null
        }).then(avatarBuffer => {
            avatar.src = avatarBuffer
            circleImg(ctx, avatar, 525, 92, 46)
            saveImageFiles(canvas.toDataURL()).then(() => {
                resolve(context.body = response)
            }).catch(err => console.log(err))
        }).catch(err => console.log(err))
    })
}

function requestAsync(options) {
    return new Promise((resolve, reject) => {
        request(options, (err, res, body) => {
            if (err) {
                reject(err)
            } else {
                resolve(body)
            }
        })
    })
}
/**
 * 绘制圆角图片
 * @param  {context} ctx canvas实例
 * @param  {object} img image实例
 * @param  {int} x   x 偏移
 * @param  {int} y   y 偏移
 * @param  {int} r   半径
 * @return {[type]}  [description]
 */
function circleImg(ctx, img, x, y, r) {
    ctx.save()
    var d = 2 * r
    var cx = x + r
    var cy = y + r
    ctx.arc(cx, cy, r, 0, 2 * Math.PI)
    ctx.clip()
    ctx.drawImage(img, x, y, d, d)
    ctx.restore()
}

/**
 * [saveImageFiles] 
 * 写入文件
 * @return {String} Image数据
 */
function saveImageFiles(imgData) {
    return new Promise(async(resolve, reject) => {
        let _base64Data = imgData.replace(/^data:image\/\w+;base64,/, "")
        let _dataBuffer = new Buffer(_base64Data, 'base64')
        let _fileName = `${Date.now()}.png`
        let _localFile = _fileName
        try {
            fs.writeFileSync(_localFile, _dataBuffer)
            resolve(uploadImageFiles(_fileName, _localFile))
        } catch (e) {
            console.log(e)
        }
    })
}

/**
 * [uploadImageFiles description]
 * 上传图片到腾讯云
 * @param  {String} key       [文件名称]
 * @param  {String} localFile [文件路径]
 * @return {object}           [返回数据]
 */
function uploadImageFiles(key, localFile) {
    return new Promise((resolve, reject) => {
        let params = {
            Bucket: tengxun_cos.Bucket,
            Region: tengxun_cos.Region,
            Key: key,
            FilePath: localFile
        }
        cos.sliceUploadFile(params, (err, data) => {
            if (err) {
                reject(deleteLocalImages(localFile))
            } else {
                let imageSrc = 'http://demo/' + data.Key
                response.Data = imageSrc
                resolve(deleteLocalImages(localFile))
            }
        })
    })
}
/**
 * 删除本地图片
 * @param  {img address} localFile [description]
 * @return {[type]}           [description]
 */
function deleteLocalImages(localFile) {
    fs.unlinkSync(localFile)
}


module.exports = processingPicture
6 回复

“失败的请求” 描述的太模糊了

@lellansin 可能是代码导致的 就是请求没有任何结果返回 可能 没有走到 context.body = response 这行这里吧 我估计是和Promise我的用法出了什么问题导致的。。 我如果全用await 做成同步的话就会导致服务器500 但是改成Promise 发现 只有 21个请求有返回,其余的全都没有返回结果 而且测试那边说请求的时长很长,逻辑很简单 感觉应该是代码出了啥问题 但是0.0 新人不知道怎么检测

从你的描述里,看到问题貌似不止一个。先从 console.log 开始吧,多加几个打印,可能超时的地方都加一下日志输出。然后看一下流程走到哪里没走下去了。

@lellans<br/><br/><a class=“form” href=“https://github.com/shinygang/Vue-cnodejs”>I‘m webapp-cnodejs-vue</a>

@enternull v北方的VC<br/><br/><a class=“form” href=“https://github.com/shinygang/Vue-cnodejs”>I‘m webapp-cnodejs-vue</a>

AD<br/><br/><a class=“form” href=“https://github.com/shinygang/Vue-cnodejs”>I‘m webapp-cnodejs-vue</a>

回到顶部