Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用节点蓝鸟。API返回信息太晚_Javascript_Node.js_Bluebird - Fatal编程技术网

Javascript 使用节点蓝鸟。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) {

我试图找出如何在“hhh”myresult中不被定义。发生的事情是,jjj返回为hello,然后我得到了未定义的myresult,然后“here”返回所有api数据。似乎api返回的时间太长了,所以它给出了未定义的结果。发生这种情况时,我无法使用数据更新表单。有什么建议吗

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-因为看起来你可能是新来的,如果这回答了你的问题,那么你可以通过点击答案左边的复选标记向社区表明这一点。这也将为你赢得一些声誉点在这里遵循正确的程序。