[英]Laravel Dusk - execute javascript script and wait for promise to be resolved to return the value
I want to run a script that will wait for the promise to return the value. 我想运行一个脚本,该脚本将等待Promise返回值。
$dusk->script('return //something');
The javascript function I want to run is a promise. 我要运行的javascript函数是一个承诺。
fetch(url).then(r => r.blob()).then(blob => {
var reader = new FileReader();
reader.onload = function() {
var b64 = reader.result.replace(/^data:.+;base64,/, '');
console.log(b64); // I want to return this value
};
reader.readAsDataURL(blob);
});
I want to return the b64
variable, but this won't happen. 我想返回
b64
变量,但这不会发生。
$b64 = $dusk->script("
var b64;
fetch(url).then(r => r.blob()).then(blob => {
var reader = new FileReader();
reader.onload = function() {
b64 = reader.result.replace(/^data:.+;base64,/, '');
};
reader.readAsDataURL(blob);
});
// When `b64` is ready, I want to return it
return b64;
");
This is one possibility. 这是一种可能性。 I would assume it works with dusk/selenium as well.
我认为它也适用于黄昏/硒。 The clue is that the onload function is basically a callback, so we want to use that callback to resolve the promise.
线索是onload函数基本上是一个回调,因此我们想使用该回调来解决承诺。 If you want sync-looking code, async/await could do that for you as well, but the end result is the same, a promise gets returned so you can continue the promise chain.
如果您想要同步代码,async / await也可以为您执行此操作,但是最终结果是相同的,将返回一个保证,因此您可以继续保证链。
fetch(url)
.then(r => r.blob())
.then(blob => new Promise(( resolve ) => {
var reader = new FileReader();
reader.onload = function() {
var b64 = reader.result.replace(/^data:.+;base64,/, '');
resolve( b64 );
};
reader.readAsDataURL(blob);
})
.then( b64 => {
// do something with b64
});
This does imply that you can't return it to the outer $b64 =
though. 这确实意味着您不能将其返回到外部
$b64 =
。
Edit: So instead of 编辑:所以而不是
$b64 = fetch(url)
.then( response => ... )
.then( blob => ... )
.then( image => ... );
renderImage( $b64 );
You would want to do 你想做
fetch(url)
.then( response => ... )
.then( blob => ... )
.then( image => ... )
.then( renderImage );
Or: 要么:
var $b64 = fetch(url)
.then( response => ... )
.then( blob => ... )
.then( image => ... );
$b64.then( renderImage );
Edit 2: 编辑2:
Do not wait for the actual Promise, wait for the result of the promise to show up on the screen, so as per the dusk docs, you give the promise 5 seconds to resolve before dusk throws an error. 不要等待实际的Promise,而是等待诺言的结果出现在屏幕上,因此根据黄昏文档,您会在黄昏引发错误之前给诺5秒钟来解决诺言。
If the Promise would render the result on the page, try detecting a change in the image tag the image will be rendered to. 如果Promise会将结果呈现在页面上,请尝试检测将要呈现图像的图像标签中的更改。
$dusk->script("
fetch(url).then(r => r.blob()).then(blob => {
var reader = new FileReader();
reader.onload = function() {
var b64 = reader.result.replace(/^data:.+;base64,/, '');
document.querySelector( 'body' ).classList.add( 'loaded_image' );
};
reader.readAsDataURL(blob);
});
");
$dusk->waitUntil('body.loaded_image');
Solution: 解:
$dusk->script('
var url = document.getElementById("img_file").getAttribute("src");
fetch(url)
.then(r => r.blob())
.then(blob => new Promise(( resolve ) => {
var reader = new FileReader();
reader.onload = function() {
var b64 = reader.result.replace(/^data:.+;base64,/, "");
resolve( b64 );
};
reader.readAsDataURL(blob);
}))
.then( b64 => {
$("body").append(`<input id="b64string" value="${b64}">`);
});
');
// wait until ajax to be finished
$dusk->waitUntil("!$.active", 30);
$b64Img = $dusk->script("return document.getElementById('b64string').value;"); // this returns array
dd($b64Img[0]); // works!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.