简体   繁体   English

等待一个 function 结束后再开始下一个

[英]Wait the end of a function before to start the next

I'm working on Ionic v4 with Angular.我正在使用 Angular 开发 Ionic v4。

In my project i use the BLE to communicate with a raspberry.在我的项目中,我使用 BLE 与树莓派进行通信。

I have several step:我有几个步骤:

  1. Search Device around me搜索我周围的设备
  2. Connect to this device连接到此设备
  3. Activate Notification激活通知
  4. Send Messages发送信息

Currently i have something like:目前我有类似的东西:

this.ble.scan().subscribe(result => {
  if (device === theDeviceIWant) {
    this.ble.connect(device.id).subscribe(result => {
      this.ble.startNotification(infosaboutDevice).subscribe(result => {
        // Message 1
        this.ble.writeWithoutResponse(infos, message).then(result => {
          // Message 2
          this.ble.writeWithoutResponse(infos, message).then(result => { 
            // Message 3
            this.ble.writeWithoutResponse(infos, message).then(result => {
              // Message X
              this.ble.writeWithoutResponse(infos, message).then(result => {
              })
            })
          })
        })
      })
    })
  })
}

I want to do something like that:我想做这样的事情:

this.myScan();
this.myConnect();
this.myNotification();
this.myMessage('Text 1');
this.myMessage('Text 2');
this.myMessage('Text X');

The probleme: My function 'myConnect' don't wait the end of 'myScan' to start.问题:我的 function 'myConnect' 不要等到 'myScan' 结束才开始。 So somme stuff needed by 'myConnect' is do in 'myScan'.所以'myConnect' 需要的一些东西是在'myScan' 中完成的。

I already try to use 'async/await' but does not work.我已经尝试使用 'async/await' 但不起作用。 I think i don't use it correctly:我认为我没有正确使用它:

 await this.myConnect().then(async () => {
       await this.myNotification().then(async () => {
           await this.myMessage('03020000').then(async () => {
               await this.myMessage('010100').then(async () => {
                   await this.myMessage('020200' + this.random.toString(16));
               });
           });
       });
   });

Help me to understand how to create a function who wait the end of the before one to start:D帮助我了解如何创建一个等待前一个结束的 function 开始:D

Just use async/await OR then只需使用 async/await 或then

 await this.myConnect();  // this awaits the Promise returned by myConnect to be resolved
 await this.myNotification();  // same for this Promise
 await this.myMessage('03020000');  // and so on...
 await this.myMessage('010100');
 await this.myMessage('020200' + this.random.toString(16));

The keyword await makes JavaScript wait until that promise settles and returns its result.关键字 await 使 JavaScript 等到 promise 解决并返回其结果。

So you dont need to use then in await this.myConnect().then(()=>{});所以你不需要在await this.myConnect().then(()=>{});中使用then

use await this.myConnect() ;使用await this.myConnect()

Below is example which help you understand better以下是帮助您更好理解的示例

function SignalOne() {

        return new Promise((resolve, reject) => {
            setTimeout(()=>{
                resolve('Hello iam signal one');
            }, 2000);
        });

    }

    function SignalTwo() {

        return new Promise((resolve, reject) => {
            setTimeout(()=>{
                resolve('Hello iam signal Two');
            }, 1000);
        });

    }

    async function sendSignal() {
        let one = await SignalOne();
        let two = await SignalTwo();
        console.log(one);
        console.log(two);

    }

    sendSignal();

Try this:尝试这个:

async myScan() {
   // do things
}

ngOnInit() {
   const scan = this.myScan(); // myScan doesn't actually have to return here
   await scan;
   const connect = this.myConnect();
   await connect;
   // more stuff
}

This is essentially what Promises are made for.这基本上就是 Promise 的目的。

A Promise is an object representing the eventual completion or failure of an asynchronous operation. Promise 是一个 object 代表异步操作的最终完成或失败。

You can read up about Promises here . 您可以在此处阅读有关 Promises 的信息 Once you read thru that, I left an example for you below to demonstrate how to use a Promise :阅读完之后,我在下面为您留下了一个示例,以演示如何使用Promise

 //Wrap the operation you want to wait for in a Promise (in this case: setTimeout) const promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('3 seconds have passed'); }, 3000); }); //Once the operation is resolved the callback in the.then will be called promise.then(val => document.querySelector('#target').innerHTML = val);
 <div id="target">This message will change once the operation is resolved in 3 seconds.</div>

I would embrace Observables.我会拥抱 Observables。 Looking at what you want..看你想要什么。。

  1. Search Device around me搜索我周围的设备
  2. Connect to this device连接到此设备
  3. Activate Notification激活通知
  4. Send Messages发送信息

1 and 2 would be chained with switchMap , as responses depend on each other. 1 和 2 将与switchMap链接,因为响应相互依赖。 Then 3 and 4 could be performed in order, but not dependent on each other, therefore we could use concat with those.然后 3 和 4 可以按顺序执行,但不相互依赖,因此我们可以将它们与concat一起使用。 (If this is not correct flow, adjust accordingly with these two operators). (如果这不是正确的流量,请使用这两个运算符进行相应调整)。

So I suggest the following:所以我建议如下:

import { never } from 'rxjs';
import { switchMap, concat } from 'rxjs/operators';

// ...

this.ble.scan().pipe(
  switchMap((device) => {
    if (device === theDeviceIWant) { 
      return this.ble.connect(device.id)
    }
    // terminates rest of code
    return never();
  }),
  concat(
    this.ble.startNotification(...),
    this.ble.writeWithoutResponse(...)
  )
).subscribe(data => console.log(data))

You're so close!你这么近! Rather than using .then and async just use one or the other.而不是使用.thenasync只使用其中一个。 Here are a few ways to accomplish what you are trying to do:这里有一些方法来完成你正在尝试做的事情:

Using .then :使用.then

This is your typical chaining syntax.这是典型的链接语法。 Promises can be chained using .then() and passing in a function. Promise 可以使用.then()链接并传入 function。 If the return value is a value (not a Promise ) then it will resolve to that value.如果返回值是一个值(不是Promise ),那么它将解析为该值。 But if it did return a Promise then it will chain together and your next .then() will resolve to the "inner" async call result.但是,如果它确实返回了Promise那么它将链接在一起,并且您的下一个 .then .then()将解析为“内部”异步调用结果。

// Message 1
return this.ble.writeWithoutResponse(infos, message).then(result1 => {
  // Message 2
  return this.ble.writeWithoutResponse(infos, message);
}).then(result2 => { 
  // Message 3
  return this.ble.writeWithoutResponse(infos, message);
)}.then(result3 => {
  // Message X
  return this.ble.writeWithoutResponse(infos, message);
}).then(result4 => {  })

Using async / await使用async / await

This approach achieves the same result but uses special keywords to automatically chain promises together.这种方法实现了相同的结果,但使用特殊的关键字自动将 Promise 链接在一起。 async / await allows you to skip the .then() and return calls so you can invoke your async functions as if they were synchronous. async / await允许您跳过.then()return调用,以便您可以调用异步函数,就好像它们是同步的一样。

// Message 1
let result1 = await this.ble.writeWithoutResponse(infos, message)
// Message 2
let result2 = await this.ble.writeWithoutResponse(infos, message);
// Message 3
let result3 = await this.ble.writeWithoutResponse(infos, message);
// Message X
let result4 = await this.ble.writeWithoutResponse(infos, message);

To learn more about Promise 's and async javascript, check out these resources:要了解有关Promise和异步 javascript 的更多信息,请查看以下资源:

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

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