Javascript 回调以确保异步api请求已完成
我知道关于这个问题已经有几十万条线索了,我已经研究这个问题好几天了,但我仍然不知道如何将我所经历的例子应用到我的案例中 我从如下API调用开始:Javascript 回调以确保异步api请求已完成,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,我知道关于这个问题已经有几十万条线索了,我已经研究这个问题好几天了,但我仍然不知道如何将我所经历的例子应用到我的案例中 我从如下API调用开始: const getReleaseUrl = (discogsId) => { db.getRelease(discogsId, (err, data) => { return data.uri }) } console.log(getReleaseUrl("53130")); // => undefined 如
const getReleaseUrl = (discogsId) => {
db.getRelease(discogsId, (err, data) => {
return data.uri
})
}
console.log(getReleaseUrl("53130"));
// => undefined
如何确保我的应用程序首先接收数据,防止未定义的返回?我是否需要以某种方式确保db
首先使用我的客户端id定义并连接到远程数据库?我是否需要编写一个函数,以某种方式捕获未定义的结果,并不断地运行API调用,直到结果有所不同?设置超时似乎不是一个好的永久解决方案。我试着写一个这样的承诺链,得到了TypeError:db.getRelease(…)。那么这不是一个函数错误:
const getReleaseUrl = (discogsId) => {
db.getRelease(discogsId, (err, data) => {
return data
})
.then((data) => {
return data.uri
})
}
console.log(getReleaseUrl("53130"));
看起来db.getRelease已经接受了回调,所以您可以在那里处理成功和错误
getReleaseUrl函数不返回任何内容。从arrow函数中删除大括号或添加return语句 使用承诺
var promise1 = new Promise(function(resolve, reject) {
resolve('Success!');
});
promise1.then(function(value) {
console.log(value);
// expected output: "Success!"
});
按照以下步骤操作:
请参见在db.getRelease
之前添加的返回:
使用node.jsutil
提示db.getRelease
var util = require('util');
var getRelease = util.promisify(db.getRelease);
返回全部数据:
const getReleaseUrl = (discogsId) => {
return getRelease(discogsId);
}
或返回特定的一个:
const getReleaseUrl = (discogsId) => {
return getRelease(discogsId)
.then(function(data){
return data.uri;
});
}
按照这种编码方式,您的控制台消息不可能返回任何内容,除非未定义
对于初学者,您的方法没有return语句。当然,回调有一个return语句,但这并不重要。没有返回语句,没有要记录的内容。使用您定义的方法,最好是在回调中放置一条控制台消息
const getReleaseUrl = (discogsId) => {
db.getRelease(discogsId, (err, data) => {
console.log(data.uri);
return data.uri
})
}
getReleaseUrl("53130");
更好的替代方法是重写函数以接受回调作为参数:
const getReleaseUrl = (discogsId, callback) => {
db.getRelease(discogsId, callback);
}
getRelaseUrl("53130", (err, data) => {
console.log(data.uri);
});
在这里,您正在将关于如何处理返回数据的逻辑移出主函数,这给了您更多的灵活性。它还确保在数据准备就绪之前不会调用日志消息。您可以通过回调传递回调,也可以使用承诺。
让我们看看承诺选项:
const getReleaseUrl = (discogsId) => {
return new Promise((resolve, reject) => {
db.getRelease(discogsId, (err, data) => {
if (err) {
reject(err);
}
resolve(data);
});
});
};
getReleaseUrl("53130")
.then(console.log);
.catch(console.error);
问题是,正如您所说,对db.getRelease的调用是异步的,因此getReleaseUrl不会返回任何内容。
查看Pop-A-Stash的回答,找到一个回调选项。它返回我的Discogs客户端数据,而不是discogsId的音乐发布数据
是--它将返回你可以调用的承诺。然后(函数(数据){//access data here})我不得不取消选中你的回答,因为它毕竟对我来说不起作用。我有var apiGetCall=util.promisify(db.getRelease(discogsId))
和return apiGetCall
给出的“原始”参数必须是Function类型的
error。无论最终使用回调、承诺还是异步/等待,都可能重复,请阅读对相关问题的回答,以了解发生了什么:@BrahmaDev该线程是一个很好的资源,我在开始该线程之前已经看到了它,但示例太广泛,我无法提出自己的解决方案k,但最终该逻辑将进入路由定义,它只需要返回值,没有控制台日志记录。我知道OP中的代码以控制台日志结尾,但这更多是为了查看代码输出的内容console.log(getReleaseUrl('53130',(err,data)=>{return data.uri}))
再次给出undefined,当然它返回undefined。您必须了解异步函数与同步函数的工作方式不同。它们不返回直接值。您必须使用此回调模式或承诺。无论哪种方式,您都将定义一个稍后将被调用的函数。没办法。好吧,我现在明白了,但你的主要回复中没有解释