简体   繁体   English

异步等待无法正常工作

[英]async await not working properly

I am new to JavasSript's async , await and promise features.我是 JavasSript 的asyncawaitpromise功能的新手。

What I am doing is,我正在做的是,

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);
        }
    });
}

I am calling this functions in one switch case like,我在一个 switch case 中调用这个函数,比如,

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

But while response shows sendImageMessage() last because this function may be not getting ready when I am sending imageUrl to generate a response.但是,虽然响应最后显示sendImageMessage()因为当我发送imageUrl以生成响应时,此函数可能没有准备好。

Note this answer was written against the original question and not later edits made by the OP.请注意,此答案是针对原始问题编写的,而不是 OP 稍后进行的编辑。


An async function is asynchronous. async函数是异步的。 Other functions will not wait for it.其他功能不会等待它。

So you call sendTextMessage which calls callSendAPI and then the rest of the program carries on.所以你调用sendTextMessage调用callSendAPI然后程序的其余部分继续。

callSendAPI runs asynchronously. callSendAPI异步运行。 It calls request and waits for the promise returned by request to be resolved.它调用request ,并等待返回的承诺, request予以解决。 When it has resolved, callSendAPI picks up the return value of request (well, it would if you captured the return value) and then continues with the next line (only there isn't a next line).当它解决后, callSendAPI获取request的返回值(好吧,如果你捕获了返回值,它会)然后继续下一行(只有没有下一行)。


async / await do not make asynchronous code synchronous. async / await不会使异步代码同步。 They just make it look like it in inside the function declared as async which, itself, becomes asynchronous.他们只是让它看起来像在声明为async的函数内部,它本身就变成了异步。


You could put your three function calls in an async function of their own, make sure each one returns a Promise, and then call each of those three with await .您可以将三个函数调用放在它们自己的async函数中,确保每个函数都返回一个 Promise,然后使用await调用这三个函数中的每一个。


See also How do I return the response from an asynchronous call?另请参阅如何从异步调用返回响应? . .

I hope that all you want todo is process some operations in strict order.我希望您要做的只是按照严格的顺序处理一些操作。

This is why async and await in ES6 exists.这就是为什么 ES6 中存在 async 和 await 的原因。

So by example it may be like this do A then do B then do C or A > B > C所以举个例子,它可能是这样做A然后做B然后做C或A> B> C

As you can see the last method do3 has only 500 ms delay but it is executed as last and not as first one.正如您所看到的,最后一个方法 do3 只有 500 毫秒的延迟,但它作为最后一个而不是第一个执行。 Without async and await operators it would be executed as first function and this is default behavior of JavaScript execution.如果没有 async 和 await 运算符,它将作为第一个函数执行,这是 JavaScript 执行的默认行为。 Broser will execute sync code as first and async after. Broser 将首先执行同步代码,然后执行异步代码。 But not with async and await anymore :)但不再使用 async 和 await 了 :)

You should also know that if you prefix string, number of function with await then the will be transformed into promise automatically.您还应该知道,如果您在 string、number of function 前面加上 await,那么它们将自动转换为 promise。

The console will print :控制台将打印:

'juraj1' 'juraj1'
'juraj2' 'juraj2'
'juraj3' 'juraj3'

here is simple example :这是一个简单的例子:

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();

You have to await the API calls:您必须等待 API 调用:

 await callSendAPI(messageData);

And therefore the functions these calls are in need to be async too and await ed when called and so on.因此,这些调用所需的函数也需要async并在调用时await ,依此类推。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM