Làm cách nào tôi có thể "ngủ" một chương trình Dart


102

Tôi muốn mô phỏng cuộc gọi dịch vụ web không đồng bộ trong ứng dụng Dart của mình để thử nghiệm. Để mô phỏng tính ngẫu nhiên của các cuộc gọi giả này phản hồi (có thể không theo thứ tự), tôi muốn lập trình các cuộc gọi giả của mình để chờ (ngủ) trong một khoảng thời gian nhất định trước khi trả về 'Tương lai'.

Tôi có thể làm cái này như thế nào?

Câu trả lời:


111

Bạn cũng có thể sử dụng nhà máy Future.delayed để hoàn thành một tương lai sau một thời gian trì hoãn. Dưới đây là một ví dụ về hai hàm trả về một chuỗi không đồng bộ sau một khoảng thời gian trễ:

import 'dart:async';

Future sleep1() {
  return new Future.delayed(const Duration(seconds: 1), () => "1");
}

Future sleep2() {
  return new Future.delayed(const Duration(seconds: 2), () => "2");
}

8
Mục đích là () => "1"gì?
Daksh Gargas

2
Tôi đoán không sử dụng, nó chỉ là một giữ chỗ để làm computaions của bạn
Anil8753

66

Không phải lúc nào nó cũng là điều bạn muốn (đôi khi bạn muốn Future.delayed), nhưng nếu bạn thực sự muốn ngủ trong ứng dụng dòng lệnh Dart của mình, bạn có thể sử dụng dart: io's sleep():

import 'dart:io';

main() {
  sleep(const Duration(seconds:1));
}

Tốt! Thật không may, thông tin này rất khó tìm thấy tại trang web chính thức.
Timur Fayzrakhmanov

11
'phi tiêu: io' thư viện không có sẵn nếu bạn đang xây dựng một ứng dụng web
adeel41

4
Từ tài liệu: Sử dụng tài liệu này một cách cẩn thận vì không có hoạt động không đồng bộ nào có thể được xử lý một cách riêng lẻ khi nó bị chặn trong cuộc gọi [ngủ].
bartektartanus

1
CẢNH BÁO : Đây là đồng bộ !!! Nó sẽ dừng chuỗi chính! (Tôi thật ngu ngốc rằng tôi đã làm await sleep()và mong đợi các công việc khác chạy khi đang ngủ :(
ch271828n

1
Sự khác biệt giữa hai người trong số họ (sleep vs Future.delayed) là gì? Điều gì đang xảy ra ở hậu trường trong cả hai kịch bản?
Tomas Baran

62

Phiên bản 2019:

Trong mã không đồng bộ

await Future.delayed(Duration(seconds: 1));

Trong mã đồng bộ

import 'dart:io';

sleep(Duration(seconds:1));

Lưu ý: Thao tác này chặn toàn bộ quá trình (cô lập), vì vậy các chức năng không đồng bộ khác sẽ không được xử lý. Nó cũng không có sẵn trên web vì Javascript thực sự chỉ dành cho không đồng bộ.


Sự khác biệt giữa hai người trong số họ (sleep vs Future.delayed) là gì? Điều gì đang xảy ra ở hậu trường trong cả hai kịch bản?
Tomas Baran

3
sleep()chặn hoàn toàn toàn bộ vùng cách ly. Không có mã Dart nào sẽ chạy trong khi nó đang ngủ. Nó có thể biên dịch thành một cái gì đó giống như C ++ std::this_thread::sleep_for. Future.delayed()lên lịch để hàm không đồng bộ tiếp tục lại sau đó, nhưng sau đó nó trả lại quyền điều khiển cho vòng lặp sự kiện Dart để các hàm không đồng bộ khác có thể tiếp tục chạy.
Timmmm

24

Tôi nhận thấy rằng có một số triển khai trong Dart làm cho việc thực thi mã trì hoãn:

new Future.delayed(const Duration(seconds: 1)); //recommend

new Timer(const Duration(seconds: 1), ()=>print("1 second later."));

sleep(const Duration(seconds: 1)); //import 'dart:io';

new Stream.periodic(const Duration(seconds: 1), (_) => print("1 second later.")).first.then((_)=>print("Also 1 second later."));
//new Stream.periodic(const Duration(seconds: 1)).first.then((_)=>print("Also 1 second later."));

16

Đối với cú pháp Dart 2+, trong ngữ cảnh hàm không đồng bộ:

import 'package:meta/meta.dart'; //for @required annotation

void main() async {
  void justWait({@required int numberOfSeconds}) async {
    await Future.delayed(Duration(seconds: numberOfSeconds));
  }

  await justWait(numberOfSeconds: 5);
} 

3

Đây là một mô hình hữu ích có thể lấy một tham số tùy chọn để mô phỏng một lỗi:

  Future _mockService([dynamic error]) {
    return new Future.delayed(const Duration(seconds: 2), () {
      if (error != null) {
        throw error;
      }
    });
  }

Bạn có thể sử dụng nó như thế này:

  await _mockService(new Exception('network error'));

-2

Tôi cũng cần đợi một dịch vụ hoàn tất trong quá trình kiểm tra đơn vị. Tôi đã triển khai theo cách này:

void main()
{
    test('Send packages using isolate', () async {
        await SendingService().execute();
    });
    // Loop to the amount of time the service will take to complete
    for( int seconds = 0; seconds < 10; seconds++ ) {
        test('Waiting 1 second...', () {
            sleep(const Duration(seconds:1));
        } );
    }
}
...
class SendingService {
    Isolate _isolate;
    Future execute() async {
        ...
        final MyMessage msg = new MyMessage(...);
        ...
        Isolate.spawn(_send, msg)
            .then<Null>((Isolate isolate) => _isolate = isolate);
    }
    static void _send(MyMessage msg) {
        final IMyApi api = new IMyApi();
        api.send(msg.data)
            .then((ignored) {
                ...
            })
            .catchError((e) {
                ...
            } );
    }
}

Điều này không tốt vì bạn thường không biết dịch vụ của mình mất bao nhiêu thời gian để hoàn thành.
mcfly
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.