我想宣传ODM / ORM。如何使用find()
,insert()
,update()
等其他方法实现promise接口。所以你可以做到
var Users = Collection('users')
Users.find({name: 'joe'})
.then(users => users.update({name: 'jim'))
.then(console.log)
我想继承自Promise
,但是如何自定义then()以返回您的ORM实例,以确保我们使用按顺序进行的所有查询来处理实例。
现在我正在使用合成但是我必须代理每个方法调用都变得难看。
例如:
var Promise = require('bluebird')
var Collection = function(Storage, name) {
this.promise = new Promise(function(resolve, reject) {
self.resolve = resolve
self.reject = reject
})
}
Collection.prototype.find = function(query) {
// async query stuff here
Storage.doAsyncQueryStuff(function (err, results) {
err && this.reject(err)
this.resolve(results)
})
}
Collection.prototype.then = function(callback) {
var self = this
this.promise.then(function() {
callback && callback.apply(self, arguments)
})
return this
}
我想做的是:
var inherits = require('util').inherits
var Promise = require('bluebird')
var Collection = function(Storage, name) {
var self = this
// error here
Promise.call(
this,
function(resolve, reject) {
self.resolve = resolve
self.reject = reject
})
}
inherits(Collection, Promise)
我似乎无法将Promise初始化。或者我应该以不同的方式做这件事?
答案 0 :(得分:1)
经过一些研究后,我发现在ORM实例中继承承诺不是一个好主意,因为以下内容:
Promises以递归方式解析,每个都返回从最后一个解析的new promise
。
例如:
var debug = console.log
var promise1 = new Promise((r, e) => {
r(1)
})
var promise2 = new Promise((r, e) => {
r(2)
})
var promise3 = promise1.then(data => promise2)
debug('promise1 === promise1', promise1 === promise1) // true
debug('promise3 === promise1', promise3 === promise1) // false
debug('promise3 === promise2', promise3 === promise2) // false
promise1将首先解析promise2并使用已解析的值作为promise1的分辨率值。然后,promise1将返回一个解析为promise1值的新promise(promise3)。
这很重要,因为承诺解决状态是不可变的,但承诺是可链接的。
要在ODM中有效地为每个then()调用返回一个新的promise,同时保留它的当前状态,需要进行优化,例如使ORM状态数据不可变或从全局存储(注册表)引用,同时保持它的当前{{1唯一的(过滤器,排序,加载的关系)等。将promise接口像then(),catch()组合到ORM上更简单,因为Promise规范是非常宽容的。
由于检查只允许Promise类型的Object创建实例,因此阻止了通过继承扩展bluebird。 https://github.com/petkaantonov/bluebird/issues/325
Bluebird以及FF,Chrome和Node.js内置的Promise无法通过ES5继承扩展。它们都需要Promise实例来实例化。
ECMA262定义了可继承的Promise对象。 http://www.ecma-international.org/ecma-262/6.0/#sec-promise-constructor
使用ES6类语法,您可以扩展内置的浏览器承诺。
query
这可能适用于使用Babel的Node.js。
您可以通过直接在ES5中设置class MyPromise extends Promise {}
属性来扩展bluebird和内置promise。
__proto__
虽然我不推荐它,但/**
* @class MyPromise
* @extends Promise
*/
var MyPromise = function () {
var resolve, reject
var promise = new Promise(function(_resolve, _reject) {
resolve = _resolve
reject = _reject
})
promise.__proto__ = this.__proto__
promise.resolve = resolve
promise.reject = reject
return promise
}
MyPromise.prototype = Object.create(Promise.prototype, { constructor: { value: MyPromise } })
MyPromise.prototype.call = function() {
this.resolve(new Date)
}
MyPromise.all = Promise.all
MyPromise.cast = Promise.cast
MyPromise.reject = Promise.reject
MyPromise.resolve = Promise.resolve
module.exports = MyPromise
不是标准虽然广泛支持。