javascript - Node callback style with promisify? "The 'original' argument must be of type function"
问题描述
I'm using util.promisify
in a Google Cloud Function to call IBM Watson Text-to-Speech, which returns a callback. My code works but I get an error message:
TypeError [ERR_INVALID_ARG_TYPE]: The "original" argument must be of type function
The documentation says
Takes a function following the common error-first callback style, i.e. taking a
(err, value) => ...
callback as the last argument, and returns a version that returns promises.
The IBM Watson callback is complicated and I can't figure out how to refactor it into the Node.js callback style. It's working, should I just ignore the error message? Here's my Google Cloud Function:
exports.IBM_T2S = functions.firestore.document('Users/{userID}/Spanish/IBM_T2S_Request').onUpdate((change) => {
let word = change.after.data().word;
let wordFileType = word + '.mp3';
function getIBMT2S(word, wordFileType) {
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const bucket = storage.bucket('myProject.appspot.com');
const file = bucket.file('Audio/Spanish/Latin_America/' + wordFileType);
var util = require('util');
var TextToSpeechV1 = require('watson-developer-cloud/text-to-speech/v1');
var textToSpeech = new TextToSpeechV1({
username: 'groucho',
password: 'swordfish',
url: 'https://stream.watsonplatform.net/text-to-speech/api'
});
var synthesizeParams = {
text: word,
accept: 'audio/mpeg',
voice: 'es-LA_SofiaVoice',
};
const options = { // construct the file to write
metadata: {
contentType: 'audio/mpeg',
metadata: {
source: 'IBM Watson Text-to-Speech',
languageCode: 'es-LA',
gender: 'Female'
}
}
};
textToSpeech.synthesize(synthesizeParams).on('error', function(error) {
console.log(error);
}).pipe(file.createWriteStream(options))
.on('error', function(error) {
console.error(error);
})
.on('finish', function() {
console.log("Audio file written to Storage.");
});
};
var passGetIBMT2S = util.promisify(getIBMT2S(word, wordFileType))
passGetIBMT2S(word, wordFileType)
});
解决方案
它正在工作,因为您正在调用getIBMT2S
并将返回值传递给util.promisfy
而不是函数本身。
这里有几个问题,首先你的getIBMT2S
函数看起来不兼容util.promisfy
,正如你从文档中强调的那样,兼容的函数应该遵循典型的回调样式签名(getIBMT2S
不带回调参数) .
其次,util.promisify
期望function
- 在您的情况下,您正在传递函数的返回值。如果getIBMT2S
更新为支持回调参数,那么正确的用法是
function getIBMT2S(word, wordFileType, cb) {
...
// be sure to invoke cb in here
}
var passGetIBMT2S = util.promisify(getIBMT2S); // <-- don't call getIBMT2S, pass it in directly
passGetIBMT2S(word, wordFileType) // <-- now invoke the wrapped function
.then(result => console.log('DONE'));
.catch(e => console.error(e));
推荐阅读
- python - 图像相似度的连体网络
- django - 如何知道用户点击注销后是否到达登录页面?姜戈
- javascript - 在 Popup 加载时从 Magnific Popup 的调用按钮访问属性
- c++ - Boost.Python 不是 .lib
- azure - 警告: foo 的数据已达到每日 0.0323 GB 的上限,并且您的应用遥测数据的收集将停止,直到 UTC 时间 2018 年 6 月 23 日上午 9:00
- java - 如何从源代码中获取使用 Gradle 构建的工件版本
- python-3.x - 如何保存和恢复 tf.estimator 模型
- android - SetScrollY 在片段中不起作用
- java - 在访问相机之前我需要按两次按钮
- python - 在整个 DataFrame 上应用函数的 Pandas 方法