getter 承诺与吸气剂配合得很好.在这里,我正在使用Node.js 8内置的 util.promisify()函数,该函数将节点样式回调("nodeback")转换为 Promise 一行.这使得编写一个 await -getter变得非常容易. var util = require('util');Foo类{获取订单(){return util.promisify(db.find)("orders",{customer:this.name});}};//我们不能在异步函数之外使用await(异步功能(){var bar = new Foo();bar.name ='约翰';//由于getter不能接受参数console.log(等待bar.orders);})(); 设置器对于二传手来说,这有点奇怪.您当然可以将Promise传递给setter作为参数,并在内部做任何事情,无论您是否等待Promise的实现.但是,我想一个更有用的用例(将我带到这里!)将用于setter,然后 await 使该操作在setter的任何上下文中完成从使用.不幸的是,这是不可能的,因为 setter函数的返回值已被丢弃. function makePromise(delay,val){返回新的Promise(resolve => {setTimeout(()=> resolve(val),delay);});}类SetTest {设置foo(p){返回p.then(function(val){//用val做一些需要花费时间的事情返回makePromise(2000,val);}).then(console.log);}};var bar = new SetTest();var promisedValue = makePromise(1000,'Foo');(异步功能(){等待(bar.foo = promisedValue);console.log('完成!');})(); 在此示例中,在 1 秒后将 Done!打印到控制台,并在 2 中打印 Foo 代码>秒之后.这是因为 await 正在等待 promisedValue 履行,并且它从未看到setter内部使用/生成的 Promise .Think of how Rails, e.g. allows you to define a property as associated with another:class Customer < ActiveRecord::Base has_many :ordersendThis does not set up a database column for orders. Instead, it creates a getter for orders, which allows us to do @orders = @customer.ordersWhich goes and gets the related orders objects.In JS, we can easily do that with getters:{ name: "John", get orders() { // get the order stuff here }}But Rails is sync, and in JS, if in our example, as is reasonable, we are going to the database, we would be doing it async.How would we create async getters (and setters, for that matter)?Would we return a promise that eventually gets resolved?{ 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; }}which would allow us to docustomer.orders.then(....);Or would we do it more angular-style, where we would automatically resolve it into a value?To sum, how do we implement async getters? 解决方案 The get and set function keywords seem to be incompatible with the async keyword. However, since async/await is just a wrapper around Promises, you can just use a Promise to make your functions "await-able".Note: It should be possible to use the Object.defineProperty method to assign an async function to a setter or getter.getterPromises work well with getters.Here, I'm using the Node.js 8 builtin util.promisify() function that converts a node style callback ("nodeback") to a Promise in a single line. This makes it very easy to write an await-able 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);})();setterFor setters, it gets a little weird.You can of course pass a Promise to a setter as an argument and do whatever inside, whether you wait for the Promise to be fulfilled or not.However, I imagine a more useful use-case (the one that brought me here!) would be to use to the setter and then awaiting that operation to be completed in whatever context the setter was used from. This unfortunately is not possible as the return value from the setter function is discarded.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!');})();In this example, the Done! is printed to the console after 1 second and the Foo is printed 2 seconds after that. This is because the await is waiting for promisedValue to be fulfilled and it never sees the Promise used/generated inside the setter. 这篇关于异步JavaScript的getter和setter怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-04 08:30
查看更多