新人关于node异步同步的问题
新人写了个demo 大概功能就是获取一张图片然后合成上传腾讯云 但是测试发现很多失败的请求 大致测试结果只有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
3 回复
“失败的请求” 描述的太模糊了
@lellansin 可能是代码导致的 就是请求没有任何结果返回 可能 没有走到 context.body = response 这行这里吧 我估计是和Promise我的用法出了什么问题导致的。。 我如果全用await 做成同步的话就会导致服务器500 但是改成Promise 发现 只有 21个请求有返回,其余的全都没有返回结果 而且测试那边说请求的时长很长,逻辑很简单 感觉应该是代码出了啥问题 但是0.0 新人不知道怎么检测
从你的描述里,看到问题貌似不止一个。先从 console.log 开始吧,多加几个打印,可能超时的地方都加一下日志输出。然后看一下流程走到哪里没走下去了。