PhantomJ không tự động chờ kết thúc của tất cả các tập lệnh đang chờ xử lý. WebPage # onLoadFinished được gọi trên sự kiện onload.
Đối với hầu hết các tập lệnh, ý tưởng ở đây là đợi cho đến khi "điều gì đó" được thực hiện hoặc đúng. Tôi rất khuyên bạn nên thử nghiệm waitfor.js. Nó thực sự quan trọng để hiểu ví dụ này trong PhantomJs.
Tôi cho rằng ví dụ của bạn là một ví dụ, nhưng hãy để tôi đề xuất câu trả lời.
Html Trang
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<title>Test</title>
</head>
<body id="body">
<script type="text/javascript">
//alert('hello');
$('body').addClass('before-dom-ready');
$(function() {
$('body').addClass('after-dom-ready');
var dfrd = $.Deferred(),
promise = dfrd.promise();
setTimeout(function() {
dfrd.resolve();
}, 5000);
promise.done(function() {
$('body').addClass('promise-executed');
$('body').text('Hello World !');
});
});
</script>
</body>
</html>
PhantomJs Script
var page = require('webpage').create();
var system = require('system');
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 10000, //< Default Max Timout is 10s
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof (testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if (!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
//console.log("'waitFor()' timeout");
typeof (onReady) === "string" ? eval(onReady) : onReady();
clearInterval(interval);
//phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
typeof (onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
clearInterval(interval); //< Stop this interval
}
}
}, 500); //< repeat check every 500ms
};
if (system.args.length != 1) {
console.log('invalid call');
phantom.exit(1);
} else {
//adapt url to your context
page.open('http://localhost:9231/demo.html', function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
waitFor(
function() {
return page.evaluate(function() {
return $('body').hasClass('promise-executed');
}) > 0;
},
function() {
page.render('page.png');
phantom.exit();
}, 10000);
}
});
}
Về cơ bản, waitFor
sẽ kiểm tra mỗi 500 ms nếu cơ thể có một lớp có tên 'promise-executed'
.
Có thể xem tập lệnh ảo đầy đủ của bạn (cũng như mã đầy đủ của bất kỳ tệp nào khác mà nó phụ thuộc vào). I E. để chúng tôi có thể dễ dàng tái tạo vấn đề. –
Vào thời điểm nào, và làm cách nào, bạn kiểm tra xem liệu lớp 'lời hứa thực thi' có hay chưa được thêm vào không? Ví dụ, bạn đã thử thực hiện lệnh gọi 'console.log' sau' dfrd.resolve() 'như thế nào? Bạn đã thử mã này trong một trình duyệt thông thường hay nói cách khác, điều gì khiến bạn nghĩ đó là một vấn đề về PhantomJS? –