0

编辑:问题与 Timer 或 HttpServer 无关,它是 dart.io sleep 功能暂停一切。它在文档中明确描述,我的错。

//

我在 HttpClient 在服务器代码中工作时遇到了奇怪的问题。我打电话

client.getUrl(Uri.parse(url)).then((HttpClientRequest response) => response.close()).then(HttpBodyHandler.processResponse).then((HttpClientResponseBody body) {
    print(body.response.statusCode);

来自 Timer 对象,它永远不会到达打印步骤。它几乎是以前版本的复制和粘贴代码,不是从 Timer 调用的,而是从 HttpRequest 调用的。工作代码在我的问题 [这里][1] 中。它在长线上失败了,我怀疑这是它永远无法到达的最后一个未来(HttpClientResponseBody)。

Timer 对象是这样创建的(只是测试代码):

main() {
  t = new Timer.periodic(new Duration(minutes: period), (Timer t) => hit());

}

void hit() {
  if (new DateTime.now().hour == 17) {
    print("syncing rock");

    loadUrlBody(furl + filter).then((content) {
      print("content loaded");

//编辑:好的,这是源代码,可能是一些微不足道的问题..我两天都想不通:-D

import 'dart:async';
import 'dart:io';
import 'package:http_server/http_server.dart';
import 'package:slack/slack_io.dart' as slack;

Timer t;
bool check;
final period = 1;
final furl = "https://****.tpondemand.com";
final filter = "somefilter";


main() {
  t = new Timer.periodic(new Duration(minutes: period), (Timer t) => hit());

}

void hit() {
  if (new DateTime.now().hour == 17) {
    print("syncing rock");

    loadUrlBody(furl + filter).then((content) {
      print("content loaded");
      Map parsedMap = content.body;
      handleMap(parsedMap);
    });
    sleep(new Duration(minutes: 60));
  } else {
    print("no time to rock " + new DateTime.now().toString());
    sleep(new Duration(minutes: period * 10));
  }
}

Future loadUrlBody(String url) {
  final c = new Completer();
  HttpClient client = new HttpClient();
  client.addCredentials(Uri.parse("https://****.tpondemand.com/api"), "tprealm", new HttpClientBasicCredentials("user", "password"));
  client.getUrl(Uri.parse(url)).then((HttpClientRequest response) => response.close()).then(HttpBodyHandler.processResponse).then((HttpClientResponseBody body) {
    print(body.response.statusCode);
    c.complete(body);
  });
  return c.future;
}



void send2Slack(String m) {
  slack.Message message = new slack.Message()..text = m;

  slack.token = 'token';
  slack.team = 'team';
  slack.send(message);
}
void handleMap(Map valueMap) {

  final Duration lostInTime = new Duration(days: 30);
  var sb = new StringBuffer();
  sb.write('K o m p o s t \n');

  for (var item in valueMap["Items"]) {
    if (item['CreateDate'] == null) item['CreateDate'] = '/Date(1403167885000+0100)/';
    if (item['ModifyDate'] == null) item['ModifyDate'] = '/Date(1403167885000+0100)/';
    if (item['LastCommentDate'] == null) item['LastCommentDate'] = '/Date(1403167885000+0100)/';

    DateTime moonLanding = new DateTime.fromMillisecondsSinceEpoch(int.parse(item['CreateDate'].substring(6, 19)));
    DateTime modifyLanding = new DateTime.fromMillisecondsSinceEpoch(int.parse(item['ModifyDate'].substring(6, 19)));
    DateTime commentLanding = new DateTime.fromMillisecondsSinceEpoch(int.parse(item['LastCommentDate'].substring(6, 19)));
    DateTime lastChangeLanding = (modifyLanding.isBefore(commentLanding)) ? commentLanding : modifyLanding;
    Duration difference = new DateTime.now().difference(lastChangeLanding);

    if (moonLanding.add(lostInTime).isBefore(new DateTime.now()) && difference.inDays > 4) {
      sb
          ..write('<https://****.tpondemand.com/entity/')
          ..write(item['Id'])
          ..write('|')
          ..write(item['Name'])
          ..write('> last change: ')
          ..write(difference.inDays)
          ..write(' days ago \n');

    }
    ;


  }
  send2Slack(sb.toString());
  print("sent to Slack");
  sb.clear();
}
4

1 回答 1

0

我创建了类似的代码,但我无法重现您的问题。
所以基本上这在从Timer.

import 'dart:io';
import 'dart:async';
import 'package:http_server/http_server.dart';

Timer t;
final period = 1;

void main(args) {
  t = new Timer.periodic(new Duration(minutes: period), (Timer t) => hit());
}

void hit() {
  loadUrlBody('http://www.google.com')
      .then((HttpClientResponseBody b) => print('hit: ${b.response.statusCode}'));
}

Future loadUrlBody(String url) {
  print('executing');
  HttpClient client = new HttpClient();
  // commented out because I have no server where I can use it
  // HttpClient client = new HttpClient()              
  //    ..addCredentials(Uri.parse("https://****.tpondemand.com/api"), "tprealm", new HttpClientBasicCredentials("user", "password"));
  return client.getUrl(Uri.parse(url))        // <== return is important here
      .then((HttpClientRequest response) => response.close())
      .then(HttpBodyHandler.processResponse)
      .then((HttpClientResponseBody body) {
        print('body: (${new DateTime.now()}) ${body.response.statusCode}');
        return body;                         // <== this value is the value the next 'then' receives. 
// for example x in: loadUrlBody('http://someurl').then(x) => doSomething(x)); 
      });
}

您不需要使用Completer. Completer 用于更复杂的用例,例如一个方法返回一个 Completer,例如一个 eventHandler 完成它。

你只需要确保你在Future任何地方都返回一个。then总是返回一个Future. 返回Future的值就是里面返回的值then

于 2014-06-27T12:38:18.377 回答