2017-02-19 35 views
0

我是Javascript新手,無法理解如何讓我的函數一個接一個運行。我想用Promise來實現這一點。如何使用Node.js中的Promise對異步調用進行排序?

我正在關注Facebook Messenger教程來製作一個聊天機器人。基本上,我想一個接一個地發送消息。

如果我把下面幾行:

sendTextMessage(recipientID, "1"); 
sendTextMessage(recipientID, "2"); 
sendTextMessage(recipientID, "3"); 
sendTextMessage(recipientID, "4"); 
sendTextMessage(recipientID, "5"); 

我要留言 「1」 被首先發送。然後,「2」,「3」等。 (而不是在隨機順序,這是這裏的問題被髮送。)


下面是相關的輔助功能。

function sendTextMessage(recipientId, messageText) { 
    var messageData = { 
    recipient: { 
     id: recipientId 
    }, 
    message: { 
     text: messageText 
    } 
    }; 

    callSendAPI(messageData); 
} 

這裏是callSendAPI函數。

function callSendAPI(messageData) { 
    request({ 
    uri: 'https://graph.facebook.com/v2.6/me/messages', 
    qs: { access_token: PAGE_ACCESS_TOKEN }, 
    method: 'POST', 
    json: messageData 

    }, function (error, response, body) { 
    if (!error && response.statusCode == 200) { 
     var recipientId = body.recipient_id; 
     var messageId = body.message_id; 

     if (messageId) { 
     console.log("Successfully sent message with id %s to recipient %s", 
      messageId, recipientId); 
     } else { 
     console.log("Successfully called Send API for recipient %s", 
     recipientId); 
     } 
    } else { 
     console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error); 
    } 
    }); 
} 

我一直停留了一段時間。任何幫助將不勝感激。

我試過了,但沒有奏效。 =(

sendTextMessage(recipientID, "1") 
.then(sendTextMessage(recipientID, "2")) 
.then(sendTextMessage(recipientID, "3")); 

回答

2

爲了使這項工作,讓你的兩個幫手功能返回承諾。因此,在callSendAPI中,您創建並返回一個,而sendTextMessage應該返回從callSendAPI獲得的相同承諾。最後,請務必將功能傳遞給您的then調用,而不是執行的一個函數。您可以使用.bind()從現有函數創建一個新函數,並指定調用時應傳遞的參數。

function callSendAPI(messageData) { 
    return new Promise(function (resolve, reject) { // *** 
     request({ 
      uri: 'https://graph.facebook.com/v2.6/me/messages', 
      qs: { access_token: PAGE_ACCESS_TOKEN }, 
      method: 'POST', 
      json: messageData 
     }, function (error, response, body) { 
      if (!error && response.statusCode == 200) { 
       var recipientId = body.recipient_id; 
       var messageId = body.message_id; 
       if (messageId) { 
        console.log("Successfully sent message with id %s to recipient %s", 
           messageId, recipientId); 
       } else { 
        console.log("Successfully called Send API for recipient %s", 
           recipientId); 
       } 
       resolve(body); // *** 
      } else { 
       console.error("Failed calling Send API", response.statusCode, 
           response.statusMessage, body.error); 
       reject(body.error); // *** 
      } 
     }); 
    }); 
} 

function sendTextMessage(recipientId, messageText) { 
    var messageData = { 
     recipient: { 
      id: recipientId 
     }, 
     message: { 
      text: messageText 
     } 
    }; 
    return callSendAPI(messageData); // *** returns promise 
} 

sendTextMessage(recipientID, "1") 
.then(sendTextMessage.bind(null, recipientID, "2")) // *** pass a function reference 
.then(sendTextMessage.bind(null, recipientID, "3")) 
.catch(function (body) { 
    console.log('aborted'); 
}); 
+0

這工作完美。非常感謝!! – Thawsitt

2

在你的榜樣,沒有承諾,這就是爲什麼它不工作。 request包不答應兼容的,但你可以安裝request-promise這是request的包裝與bluebird

假設,你正在使用request-promise你的例子是這樣的:

function callSendAPI(messageData) { 
    // return the promise so you can use the promise where you call the function 
    return request({ 
    uri: 'https://graph.facebook.com/v2.6/me/messages', 
    qs: { access_token: PAGE_ACCESS_TOKEN }, 
    method: 'POST', 
    json: messageData 
     }).then(function(body) { 
     var recipientId = body.recipient_id; 
     var messageId = body.message_id; 

     if (messageId) { 
     console.log("Successfully sent message with id %s to recipient %s", 
      messageId, recipientId); 
     } else { 
     console.log("Successfully called Send API for recipient %s", 
     recipientId); 
     } 
    }).catch(function(error) { 
     console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error); 
    }); 
} 

而對於其它功能:

function sendTextMessage(recipientId, messageText) { 
    var messageData = { 
    recipient: { 
     id: recipientId 
    }, 
    message: { 
     text: messageText 
    } 
    }; 

    return callSendAPI(messageData); 
} 

請注意,您必須返回承諾,否則調用該函數的行將無法使用該承諾。

相關問題