javascript - 解决数组推送的 promise - javascript

标签 javascript asynchronous promise async-await

我正在尝试定义一个返回 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/

相关文章:

javascript - 等效于 ES6 Promises 的 BlueBird Promise.props?

javascript - 如何等到jquery效果循环完成后再执行函数

javascript - $(window).load(function() 完全加载文档后无法执行

javascript - Jasmine,关闭默认记者

javascript - 尝试在 mysql 中存储特定的 json 键时出错

.net - 在 .NET 框架代码中使用 ThreadStatic 是过去时代的有害遗物吗?

javascript - Await 仅在 nodejs 的异步函数中有效

javascript - 使用 Javascript 从字符串中删除字符

node.js - 使用异步或回调哪一个

javascript - Web Worker 中的微任务