我正在尝试定义一个返回 promise 的函数。当给定的数组被设置时,promise 应该被解析 (push()
)。
为此,我尝试使用代理对象(受 this 影响):
let a = []
;(async function(){
const observe = array => new Promise(resolve =>
new Proxy(array, {
set(array, key, val) {
array[key] = val;
resolve();
}
}));
while(true){
await observe(a);
console.log(new Date().toLocaleTimeString(),"Blimey Guv'nor:",`${a.pop()}`);
}
})(a);
;(async function(){
await new Promise(resolve => timerID = setTimeout(resolve, 2000))
a.push('ʕ·͡ᴥ·ʔ');
a.push('¯\(°_o)/¯ ')
})(a)
我不明白为什么这不起作用。有人知道吗?
更一般地说,在推送到数组时进行 promise 解析的好方法是什么?
最佳答案
您的尝试存在的问题:
- 您在原始数组上调用
.push
,而不是代理数组。在您创建代理的地方,它不会返回给任何人:对它的任何引用都会丢失(并且将被垃圾收集)。 await
行后面的代码将异步执行,因此毕竟所有push
调用都已执行。这意味着当数组已经有两个元素时,console.log 将执行。因此,Promise 并不是满足您需求的正确工具,因为 Promise 的解析只能在所有其他同步代码运行完成后才能执行。要在执行期间同步获取通知,您需要一个同步解决方案,而 Promise 则基于异步执行。
为了完成答案,我在这里提供一个简单的同步回调解决方案:
function observed(array, cb) {
return new Proxy(array, {
set(array, key, val) {
array[key] = val;
if (!isNaN(key)) cb(); // now it is synchronous
return true;
}
});
}
let a = observed([], () =>
console.log(new Date().toLocaleTimeString(),"Blimey Guv'nor:", `${a.pop()}`)
);
a.push('ʕ·͡ᴥ·ʔ');
a.push('¯\(°_o)/¯ ');
如前所述:当您需要同步代码执行时,Promise 并不是正确的工具。
当每个push
异步执行时
如果您确定每个推送
发生在一个单独的任务中,那么您可以使用promise,其中promise作业队列在每对之间进行处理推送
调用。
例如,如果您将每个 push
调用作为输入事件处理程序的一部分,或者作为 setTimeout
计时器的回调,那么有可能:
function observed(array) {
let resolve = () => null; // dummy
let proxy = new Proxy(array, {
set(array, key, val) {
array[key] = val;
if (!isNaN(key)) resolve();
return true;
}
});
proxy.observe = () => new Promise(r => resolve = r);
return proxy;
}
let a = observed([]);
(async () => {
while (true) {
await a.observe();
console.log(new Date().toLocaleTimeString(),"Blimey Guv'nor:",`${a.pop()}`);
}
})();
setTimeout(() => a.push('ʕ·͡ᴥ·ʔ'), 100);
setTimeout(() => a.push('¯\(°_o)/¯ '), 100);
关于javascript - 解决数组推送的 promise - javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59821690/