[英]How would you display a promise object's state and value when overriding console.log
我试图在 div 中显示console.log
输出。 我通过覆盖console.log
函数来做到这一点
当我使用原始的console.log
,在控制台中会显示一个承诺(参见下面代码中的 1.):
Promise { <state>: "fulfilled", <value>: undefined }
当我越过它时,在 div 中:
[object Promise]
(参见下面代码中的 2.)
您将如何调整以下代码以使<state>
属性显示在“主”div 中?
const pause = sec => new Promise(r => setTimeout(r, 1000 * sec)) // 1. Original console.log ;(async function(){ await new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve)); let x = pause(0.5) console.log(x) await x; console.log(x) })(); // 2. Overridden console.log ;(async function(){ await new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve)); await pause(1) let divconsole = document.getElementById('main'); // Override console.log: console.log = function () { for (let i = 0; i < arguments.length; i++) { if (typeof arguments[i] === 'object') { divconsole.innerHTML += 'console.log arg ' + String(i) + ': ' + String(arguments[i]) + '<br>'; } } } let y = pause(0.5) console.log(y) await y; console.log(y) })();
<div id="main" style="width:100%;height:auto;background-color:lightblue;"> </div>
关于我为什么要问的说明:我有一个承诺在桌面浏览器中而不是在移动浏览器中解析的代码。 我正在尝试对此进行调试(没有一致的移动桌面操作系统生态系统)。 如果我可以在一个简单的例子中复制它,我可能会写一个后续问题。
您可以使用this other SO answer中的这个技巧来处理像这样的Promise
类型的参数。 该技巧要求自定义console.log
像这样异步:
function promiseState(p) {
const t = {};
return Promise.race([p, t])
.then(v =>
(v === t) ? { state: "pending" } : { state: "fulfilled", value: v },
() => { state: "rejected" }
);
}
console.log = async function(...args) {
for (let arg of args) {
if (arg instanceof Promise) {
let state = await promiseState(arg);
divconsole.innerHTML += `Promise { <state>: "${ state.state }"${ state.state === "fulfilled" ? ', <value>: ' + state.value : '' } }<br>`;
} else if (typeof arg === 'object') {
divconsole.innerHTML += 'console.log arg: ' + String(arg) + '<br>';
}
// add more else-ifs to handle strings, numbers, booleans, ... etc
}
}
自定义console.log
需要是asynchronous
因为它将承诺包装在另一个承诺中。 这是您可以做到的唯一方法。
解释:
诀窍是将承诺p
与已解决的(产生一个对象{}
) race
,如果承诺p
已经实现,则将使用其值,并且由于其值不能与另一个承诺的值相同(与我们竞争的那个,产生{}
那个,我们确定承诺已经实现。 如果我们得到的值是另一个承诺(对象{}
)的值,这意味着我们解决的承诺赢得了比赛,我们可以确定承诺p
尚未实现。
如果我们得到一个错误(意味着catch
回调被调用),promise p
被拒绝。
演示:
function promiseState(p) { const t = {}; return Promise.race([p, t]) .then(v => (v === t) ? { state: "pending" } : { state: "fulfilled", value: v }, () => { state: "rejected" } ); } console.log = async function(...args) { let divconsole = document.getElementById('main'); for (let arg of args) { if (arg instanceof Promise) { let state = await promiseState(arg); divconsole.innerHTML += `Promise { <state>: "${ state.state }"${ state.state === "fulfilled" ? ', <value>: ' + state.value : '' } }<br>`; } else if (typeof arg === 'object') { divconsole.innerHTML += 'console.log arg: ' + String(arg) + '<br>'; } } } const pause = sec => new Promise(r => setTimeout(r, 1000 * sec)); ;(async function() { await new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve)); await pause(1); let divconsole = document.getElementById('main'); let y = pause(0.5); await console.log(y); await y; await console.log(y); })();
<div id="main" style="width:100%;height:auto;background-color:lightblue;"></div>
将任何类似承诺的东西转化为真正价值的更简单方法可能是:
async function myLog(val) {
console.log(await val);
}
await
确保承诺得到解决,但也通过非承诺就好了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.