Javascript 使用节点蓝鸟。API返回信息太晚
我试图找出如何在“hhh”myresult中不被定义。发生的事情是,jjj返回为hello,然后我得到了未定义的myresult,然后“here”返回所有api数据。似乎api返回的时间太长了,所以它给出了未定义的结果。发生这种情况时,我无法使用数据更新表单。有什么建议吗Javascript 使用节点蓝鸟。API返回信息太晚,javascript,node.js,bluebird,Javascript,Node.js,Bluebird,我试图找出如何在“hhh”myresult中不被定义。发生的事情是,jjj返回为hello,然后我得到了未定义的myresult,然后“here”返回所有api数据。似乎api返回的时间太长了,所以它给出了未定义的结果。发生这种情况时,我无法使用数据更新表单。有什么建议吗 var myresult; soap.createClient(url, function(err, client) { client.getShipQuote(args, function(err, result) {
var myresult;
soap.createClient(url, function(err, client) {
client.getShipQuote(args, function(err, result) {
if (err) {
console.log(err.message);
}
console.log('RESPONSE BODY:');
console.log("here", result.return.shipQuote[0].chargesCollection);
myresult = result.return.shipQuote[0].chargesCollection;
});
});
var x="hello";
bluebird.all([x, myresult])
.spread(function(x, myresult){
console.log("jjj", x);
console.log("hhh", myresult);
response.send(x);
});
首先,蓝鸟是一个“承诺”图书馆。这意味着它创造并执行承诺。要将其用于异步操作,必须有一个返回承诺的异步操作,而不是接受常规回调的异步操作。通常,如果您开始的异步操作没有返回承诺,那么您可以通过创建新版本的异步操作来“承诺”,该异步操作使用它支持的回调来驱动承诺。然后,您可以将Bluebird的所有功能与该功能的新promisified版本一起使用
蓝鸟本身并没有任何神奇的能力知道异步操作何时完成。而且,它没有使异步操作看起来是同步的能力。它提供了管理和协调异步操作的工具,这样您就可以知道异步操作何时完成、结果何时可用以及是否/何时出现错误
看起来您有两个异步操作,一个在另一个soap.createClient()
内,另一个在client.getShipQuote()
内。而且,看起来您希望对它们进行排序,以便调用第一个,将结果传递给第二个,然后在其他一些代码中,您可以使用最终结果。以下是我建议您如何使用承诺:
const Promise = require('bluebird');
// make promisified versions of soap methods
// only have to do this once
Promise.promisifyAll(soap);
// call promisified version
soap.createClientAsync(url).then(client => {
// could perhaps do this only once beforehand if you know how to reach the client.prototype object
// before a client object is created - requires knowing a little about how the library is structured
Promise.promisifyAll(client);
return client.getShipQuoteAsync(args);
}).then(result => {
// handle final result here
response.send(...);
}).catch(err => {
// handle error here - this will catch all prior errors
console.log(err);
response.status(500).send(...);
});
如果您只想通过普通回调编程(无承诺)来实现这一点,那么您可以这样做:
soap.createClient(url, function(err, client) {
if (err) {
console.log(err.message);
// send error response
response.status(500).send(...);
} else {
client.getShipQuote(args, function(err, result) {
if (err) {
console.log(err.message);
// send error response
response.status(500).send(...);
} else {
let myResult = result.return.shipQuote[0].chargesCollection;
// send response here
response.send(...);
}
}
}
});
请注意,在异步编程的所有情况下,都必须在使结果可用的回调中(或在从那里调用的函数中)使用结果。您不能只是将结果填充到范围更大的变量中,并在回调之外的代码中使用它,因为您的计时对于该值何时可用是不正确的。这就是为什么您的代码中会出现
未定义的,因为您的代码在异步操作完成之前以及在设置值之前检查变量。只有在完成回调中,您才能真正知道该值可用。承诺不会改变这一事实。它们只是让您更容易管理和协调回调。这可能是重复的,我在getShipQuote函数中继续回调,它返回的是值,而不是未定义的值。谢谢@DominicZenon-因为看起来你可能是新来的,如果这回答了你的问题,那么你可以通过点击答案左边的复选标记向社区表明这一点。这也将为你赢得一些声誉点在这里遵循正确的程序。