异步等待无法正常工作

时间:2018-05-19 09:43:52

标签: javascript node.js asynchronous promise es6-promise

我是JavasSript的asyncawaitpromise功能的新手。

我在做的是,

async function sendTextMessage(text) {
    console.log("----1----");
    var messageData = {
        message: {
            text: text
        }
    };
   await callSendAPI(messageData);
}

async function sendImageMessage(imageUrl) {
    console.log("----2----");
    var messageData = {
        message: {
            url: imageUrl
        }
    };
  await callSendAPI(messageData);
}

async function sendQuickReply(replies) {
    console.log("----3----");
    var messageData = {
        message: {
            text: text,
            quick_replies: replies
        }
    };
   await callSendAPI(messageData);
}
async function callSendAPI(messageData) {
    await request({
        uri: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {
            access_token: config.FB_PAGE_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);
        }
    });
}

我在一个开关案例中调用这个函数,比如

async function send(){
     await sendTextMessage(text);
     await sendImageMessage(img);
     await sendQuickReply(replies)  
}
send()

但是,当响应显示sendImageMessage()时,因为当我发送imageUrl来生成回复时,此功能可能尚未准备就绪。

3 个答案:

答案 0 :(得分:1)

请注意,此答案是针对the original question编写的,而不是后来由OP编辑的。

async函数是异步的。其他功能不会等待它。

所以你打电话给sendTextMessage调用callSendAPI,然后程序的其余部分继续。

callSendAPI以异步方式运行。它调用request并等待request返回的承诺得到解决。解决之后,callSendAPI会获取request的返回值(好吧,如果你捕获了返回值,那就是它),然后继续下一行(只有下一行没有) )。

async / await不会使异步代码同步。它们只是在 inside 中将它看作是声明为async的函数,它本身变为异步。

你可以将你的三个函数调用放在他们自己的async函数中,确保每个函数都返回一个Promise,然后用await调用这三个中的每一个。

另见How do I return the response from an asynchronous call?

答案 1 :(得分:0)

您必须等待API调用:

 await callSendAPI(messageData);

因此,这些调用的函数也需要async,并且在调用时需要await等等。

答案 2 :(得分:0)

我希望你想要的只是按照严格的顺序处理一些操作。

这就是为什么ES6中存在async和await的原因。

因此,通过示例,它可能是这样做A然后做B然后做C或A> B> ç

正如您所看到的,最后一个方法do3只有500毫秒的延迟,但是它是作为最后一个而不是第一个执行的。 如果没有async和await运算符,它将作为第一个函数执行,这是JavaScript执行的默认行为。 Broser将首先执行同步代码,然后执行async。但不是用async而是等待了。)

你还应该知道,如果你在字符串前面添加了await函数,那么它将被自动转换为promise。

控制台将打印:

' juraj1'
' juraj2'
' juraj3'

这是一个简单的例子:

function do1() {
      return new Promise(resolve => {
          return setTimeout(() => resolve("juraj1"), 3000);
   });
 }
function do2() {
      return new Promise(resolve => {
            return setTimeout(() => resolve("juraj2"), 2000);
  });
 }

function do3() {
      return new Promise(resolve => {
             return setTimeout(() => resolve("juraj3"), 500);
  });
}

async function ForceAsynTOBeSync() {
    const a = await do1();

    console.log(a);

    const b = await do2();

    console.log(b);

    const c = await do3();

    console.log(c);
  }

  ForceAsynTOBeSync();