javascript - 如何使用异步 JavaScript getter 和 setter?

标签 javascript promise

想想 Rails,例如允许您将一个属性定义为与另一个关联:

class Customer < ActiveRecord::Base
  has_many :orders
end

这不会为订单 设置数据库列。相反,它为 orders 创建了一个 getter,它允许我们做

@orders = @customer.orders

它获取相关的 orders 对象。

在 JS 中,我们可以使用 getter 轻松做到这一点:

{
   name: "John",
   get orders() {
     // get the order stuff here
   }
}

但 Rails 是sync,而在 JS 中,如果在我们的示例中,如果合理的话,我们将访问数据库,我们将async

我们将如何创建异步 getter(和 setter,就此而言)?

我们会返回一个最终得到解决的 promise 吗?

{
   name: "John",
   get orders() {
     // create a promise
     // pseudo-code for db and promise...
     db.find("orders",{customer:"John"},function(err,data) {
        promise.resolve(data);
     });
     return promise;
   }
}

这将允许我们做

customer.orders.then(....);

或者我们会做更多的 Angular 风格,我们会自动将其解析为一个值吗?

总而言之,我们如何实现异步 getter?

最佳答案

getset函数关键字似乎与 async 不兼容关键词。然而,由于 async/await只是 Promise 的包装s,你可以只使用 Promise使您的功能“await -able”。

注意:应该可以使用 Object.defineProperty分配 async 的方法对 setter 或 getter 起作用。


setter/getter

Promise 与 getter 配合得很好。

在这里,我使用的是 Node.js 8 内置 util.promisify()将节点样式回调(“nodeback”)转换为 Promise 的函数在一行中。这使得编写 await 变得非常容易。 - setter/getter 。

var util = require('util');
class Foo {
  get orders() {
    return util.promisify(db.find)("orders", {customer: this.name});
  }
};

// We can't use await outside of an async function
(async function() {
  var bar = new Foo();
  bar.name = 'John'; // Since getters cannot take arguments
  console.log(await bar.orders);
})();

二传手

对于二传手来说,这有点奇怪。

您当然可以将 Promise 作为参数传递给 setter,并在其中执行任何操作,无论您是否等待 Promise 实现。

但是,我想象一个更有用的用例(将我带到这里的那个!)是先使用 setter,然后使用 await在使用 setter 的任何上下文中完成该操作。不幸的是,这是不可能的,因为 setter 函数的返回值被丢弃

function makePromise(delay, val) {
  return new Promise(resolve => {
    setTimeout(() => resolve(val), delay);
  });
}

class SetTest {
  set foo(p) {
    return p.then(function(val) {
      // Do something with val that takes time
      return makePromise(2000, val);
    }).then(console.log);
  }
};

var bar = new SetTest();

var promisedValue = makePromise(1000, 'Foo');

(async function() {
  await (bar.foo = promisedValue);
  console.log('Done!');
})();

在此示例中,Done!1 之后打印到控制台第二和Foo打印 2几秒钟后。这是因为 await正在等待promisedValue被满足,它永远不会看到 Promise在二传手内部使用/生成。

关于javascript - 如何使用异步 JavaScript getter 和 setter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28790744/

相关文章:

javascript - 通过单击按钮填充 Javascript 中的文本框

获取背景颜色的 Javascript 代码不起作用

node.js - 用下划线 map 做一些异步的事情

javascript - 如何合并数组中的重复对象值然后输出列表?

javascript - 类型 '{ period: any; prices: any; }' 的参数不可分配给类型 'MAInput' 的参数

javascript - AngularJS Controller 返回工厂但不显示在模板中

javascript - 在 React 组件中显示并行 Ajax 请求的结果

node.js - 等待所有查询完成并同时异步填充

javascript - 递归调用异步 API 调用

javascript - onload 未触发并且图像无法绘制