JeffreyZhao / wind

Asynchronous flow control in JavaScript, with JavaScript.
http://windjs.org/
1.54k stars 238 forks source link

$await is not defined #50

Closed xieren58 closed 12 years ago

xieren58 commented 12 years ago
http.getAsync = function(options) {
    return Task.create(function (t) {
        http.get(options, function(res) {
            t.complete("success", res);
        }).on("error", function(ex) {
            t.complete("failure", ex);
        });
    });
};

var downloadAsync = eval(Jscex.compile("async", function (_url) {
  var options = {
    host: url.parse(_url).host,
    port: 80,
    path: url.parse(_url).pathname,
    headers: headers
  };
  // console.log(options);
  var baseDir = './public/';
  var filename = url.parse(_url).pathname.split('/').pop();
  var r = $await(http.getAsync(options));
  console.log(r.statusCode);
  r.pipe(fs.createWriteStream(path.join(baseDir, filename)));
  r.on("end", function() {
    console.log(filename + ' end!');
  });
}));

var x = 0;
var batchDownloadAsync = eval(Jscex.compile("async", function() {
  for (; pages >= 1; pages--) {
        var _url = util.format(baseUrl, pages);
        var options = {
            host: url.parse(_url).host,
            port: 80,
            path: url.parse(_url).pathname,
            headers: headers
        };
        var resp = $await(http.getAsync(options));
        if (resp.statusCode !== 200) {
            console.log('failed to get ' + _url);
            process.exit();
        }
        var stack = '';
        resp.on('data', function(chunk){
            stack += chunk;
        });
        resp.on('end', function() {
            var fileUrl = $(stack).find('#copy_file').val();
            // if (fileUrl && fileUrl.indexOf('.mp3') !== -1) {
            //   x++;
            //   console.log(x + ' *********');
            //   downloadAsync(fileUrl).start();
            // }
            // $await(downloadAsync(fileUrl)); <- 这里的$await没法识别
            downloadAsync(fileUrl).start();  // <- 换成这个就可以
        });
        x++;
        if (x > 0 && x % 2 === 0) {
           console.log(x + ' ###############');
          $await(Jscex.Async.sleep(1000 * 60 * 4));
        }

    }
}));

try {
  batchDownloadAsync().start();
} catch (ex) {
  console.log(ex);
}
JeffreyZhao commented 12 years ago
resp.on('end', function() {
    var fileUrl = $(stack).find('#copy_file').val();
    // if (fileUrl && fileUrl.indexOf('.mp3') !== -1) {
    //   x++;
    //   console.log(x + ' *********');
    //   downloadAsync(fileUrl).start();
    // }
    // $await(downloadAsync(fileUrl)); <- 这里的$await没法识别
    downloadAsync(fileUrl).start();  // <- 换成这个就可以
});

注意你这里放在了另一个函数里,$await只能直接用在eval(Jscex.compile())里面。你这么做不是不行,不过不能用$await就是正常的了,不过问题是,你这段逻辑和你预期的逻辑是不同的。

我建议你这么做:

resp.on('data', function(chunk){
    stack += chunk;
});

$await(Async.onEvent(resp, "end")); // 等待end事件完成。

var fileUrl = $(stack).find('#copy_file').val();
$await(downloadAsync(fileUrl));

不用回调,自有onEvent辅助方法负责等待一个事件。

fantasyni commented 12 years ago

这个问题我也发现过,后来发现 $await 确实只能在 eval 下的 function 识别,如果里面还有 function 写在里面是无法识别的,解决方法就是改变逻辑

JeffreyZhao commented 12 years ago

不应该说是“改变逻辑”,就像现在这个例子,显然用onEvent就更清楚也符合逻辑原意。

一般来说代码里不需要“混用逻辑”(一会儿普通顺序一会儿又回调),或者得知道什么时候混用。