2016-08-16 75 views
0

的我想要實現一個簡單的提綱:快速路由和異步代碼 - 如何發送異步代碼的結果?

  1. 一個AJAX調用到特定的URL進行的服務器上
  2. 表達路線(以「app.js」),然後運行節點「Send.js」中的.js代碼
  3. 「Send.js」的輸出用作「res.send」方法對AJAX請求的響應。

我的問題是,「Send.js」利用異步方法等的「迴應」變量我試圖返回「res.send(響應)」沒有定義當響應發送,因爲「Send.js」中的「sendOn」函數在異步代碼執行之前完成,當然。

我知道使用回調很可能是這裏的解決方案,所以「res.send(response)」不會被調用,直到定義了響應,我不知道如何實現,這裏兩個獨立的文件:

app.js(簡化):

var send = require("./Files/Other/Send.js"); 


    app.post('/Lamp-On', function (req, res) 
    { 
     var response = send.sendOn(); 
     res.send(response); 
    }); 

Send.js(簡化):

client.open和client.sendEvent是接受一個回調既是異步方法最後一個參數,並且是外部SDK的一部分。

var sendMessage = function() 
{ 
    var data = "on"; 
    var message = new Message(data); 
    message.properties.add('Turn On'); 
    console.log('Sending message to turn the lamp: ' + message.getData()); 
    client.sendEvent(message, printResultFor('Message')); 
}; 

var connectCallback = function() { 
     if (err) { 
      console.error('Could not connect: ' + err.message); 
     } 
     else { 

      console.log('Client connected'); 

      client.on('message', function (msg) { 
       console.log('Id: ' + msg.messageId + ' Body: ' + msg.data); 
       client.complete(msg, printResultFor('completed')); 
       // reject and abandon follow the same pattern. 
       // /!\ reject and abandon are not available with MQTT 
      }); 

      client.on('error', function (err) { 
       console.error(err.message); 
      }); 

      client.on('disconnect', function() { 
       clearInterval(sendInterval); 
       client.removeAllListeners(); 
       client.connect(connectCallback); 
      }); 

      // Now call the sendMessage function. 
       sendMessage(); 
     } 
}; 

var sendOn = function() { 
    client.open(connectCallback); 
    return 
}; 

// Helper function to print results in the console 
function printResultFor(op) { 
    return function printResult(err, res) { 
     if (err !== null) { 
      console.log(op + ' error: ' + err.toString()); 
      console.log(err); 
     } 
     if (res) { 
      console.log(op + ' status: ' + res.constructor.name); 
     }; 
    }; 
} 

exports.sendOn = sendOn; 

我只是不怎麼處理這麼多的異步回調!

最後注意:我既不問也不指望任何人爲我做這件事,但我希望你能指點我正確的方向,事先要感謝。

+0

我的建議是使用[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)來處理異步調用,您將能夠這樣做'send.sendOn()。then(function(response){res.send(response);});' –

+0

我建議使用'async'模塊來避免這個問題'https://github.com/caolan/async' – abdulbarik

回答

1

的唯一方法返回的值是通過回調。即使你使用承諾也是如此。

回調是你如何返回一個值。因此,因爲sendOn()需要返回一個值,它需要接受回調(或者返回一個承諾,承諾將接受回調)。

基本上app.js應該是這樣的:

app.post('/Lamp-On', function (req, res) 
{ 
    send.sendOn(function(err,response){ 
     res.send(response); 
    }); 
}); 

一個你需要的東西習慣的功能是停止思考的子程序。而是將功能看作控制結構,如forwhileif。你用來編寫類似的代碼:

if (something) { 
    something_else(); 
} 

從概念上講,你那麼不應該有太多的麻煩:

doIf(something,function(){ 
    something_else(); 
}); 

現在到了有趣的部分。如何使sendOn()接受回調?只要將該回調一直傳遞給「返回」結果的函數即可。基本上,這個過程從程序編程倒,而不是一路返回值外碼你通過代碼一路值:

var sendOn = function (callback) { 
    client.open(function(){ 
     connectCallback(callback); // pass the CODE down to the value 
    }); 
}; 

var connectCallback = function (callback) { 
    if (err) { 
     callback(err); 
    } 
    else { 
     client.on('message', function (msg) { 
      console.log('Id: ' + msg.messageId + ' Body: ' + msg.data); 

      callback(null, msg.data); // Now pass the value to the CODE 
     }); 

     sendMessage(); 
    } 
}; 

我假設msg.data是結果。如果不相應更改。確保您將結果傳遞給您從sendOn()一路下降的回調。

+0

這真是太棒了,謝謝你簡化和解釋清楚! – Sam3000

1

從我的角度來看,以及我前幾天學到的東西,只要在sendMessage函數內添加你想要做的任何事情(如果可能的話)就可以工作。由於beeing JavaScript res對象應該從那裏訪問。

有關回調進一步提示和callbackhell:http://callbackhell.com/

+0

感謝您的鏈接 – Sam3000