2017-02-19 8 views
0

私はJavascriptを初めて使用しています。私はこれを達成するためにプロミスを使いたい。Node.jsでPromisesを使用して非同期呼び出しをシーケンスする方法は?

私はFacebookのメッセンジャーのチュートリアルに従ってチャットボットを作っています。基本的には、メッセージを次々と送っていきたいです。

私は次の行を呼び出す場合:

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

このようにするには、2つのヘルパー関数が約束を返すようにします。したがって、callSendAPIでは、1つを作成して返します。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パッケージは互換性を約束されていませんが、あなたがbluebirdrequestのラッパーである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); 
    }); 
} 

そして、他の機能のために:と仮定

、あなたはこのようになりrequest-promiseあなたの例を使用しています

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

    return callSendAPI(messageData); 
} 

約束を返さなければならないことに注意してください。それ以外の場合は、関数を呼び出す行では使用できません。

関連する問題