Laravel Dusk - 执行 javascript 脚本并等待 promise 解析为 return 值
Laravel Dusk - execute javascript script and wait for promise to be resolved to return the value
我想要 运行 一个脚本,该脚本将等待对 return 值的承诺。
$dusk->script('return //something');
我想要运行的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);
});
我想 return 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;
");
这是一种可能。我认为它也适用于 dusk/selenium。
线索是 onload 函数基本上是一个回调,所以我们想使用那个回调来解决承诺。
如果你想要看起来同步的代码,async/await 也可以为你做到这一点,但最终结果是一样的,一个 promise 得到 returned 所以你可以继续 promise 链。
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
});
这确实意味着您不能 return 它到外部 $b64 =
不过。
编辑:
所以而不是
$b64 = fetch(url)
.then( response => ... )
.then( blob => ... )
.then( image => ... );
renderImage( $b64 );
你会想做
fetch(url)
.then( response => ... )
.then( blob => ... )
.then( image => ... )
.then( renderImage );
或者:
var $b64 = fetch(url)
.then( response => ... )
.then( blob => ... )
.then( image => ... );
$b64.then( renderImage );
编辑 2:
不要等待实际的 Promise,等待 promise 的结果出现在屏幕上,因此根据 dusk 文档,你给 promise 5 秒的时间在 dusk 抛出错误之前解决。
如果 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');
解法:
$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!
我想要 运行 一个脚本,该脚本将等待对 return 值的承诺。
$dusk->script('return //something');
我想要运行的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);
});
我想 return 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;
");
这是一种可能。我认为它也适用于 dusk/selenium。 线索是 onload 函数基本上是一个回调,所以我们想使用那个回调来解决承诺。 如果你想要看起来同步的代码,async/await 也可以为你做到这一点,但最终结果是一样的,一个 promise 得到 returned 所以你可以继续 promise 链。
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
});
这确实意味着您不能 return 它到外部 $b64 =
不过。
编辑: 所以而不是
$b64 = fetch(url)
.then( response => ... )
.then( blob => ... )
.then( image => ... );
renderImage( $b64 );
你会想做
fetch(url)
.then( response => ... )
.then( blob => ... )
.then( image => ... )
.then( renderImage );
或者:
var $b64 = fetch(url)
.then( response => ... )
.then( blob => ... )
.then( image => ... );
$b64.then( renderImage );
编辑 2:
不要等待实际的 Promise,等待 promise 的结果出现在屏幕上,因此根据 dusk 文档,你给 promise 5 秒的时间在 dusk 抛出错误之前解决。
如果 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');
解法:
$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!