testcase.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<title />
<script src="jquery-3.2.1.js"></script>
<script src="underscore-1.8.3.js"></script>
<script src="backbone-1.3.3.js"></script>
<script src="testcase.js"></script>
</head>
<body />
</html>
testcase.js
class My_Collection extends Backbone.Collection {}
class My_View extends Backbone.View {
async initialize() {
let collection = new My_Collection;
collection.url = 'http://backgridjs.com/examples/territories.json';
console.log(collection);
await collection.fetch();
console.log(collection);
$.extend(this, {collection});
return this;
}
render() {
console.log('render→→→', Date.now(), this.collection);
this.collection.map(foo => foo);
}
}
const view = new My_View;
view.render();
结果是
testcase.js:13:9 Object { length: 1, models: Array[1], _byId: Object, url: "http://backgridjs.com/examples/terr…" }
testcase.js:21:9 render→→→ 1494928366647 undefined
testcase.js:22:9 TypeError: this.collection is undefined
testcase.js:16:9 Object { length: 242, models: Array[242], _byId: Object, url: "http://backgridjs.com/examples/terr…" }
请注意尽管await
无序执行。 Collection.fetch()
is documented to return一个实现承诺的jqXHR
。
我希望执行等待fetch(),将集合数据附加到视图,并渲染为不会在未定义的值上崩溃。我无法看出它出了什么问题。正确的代码是什么使它按预期工作?
答案 0 :(得分:3)
请注意以下事项:
async initialize() {
您使initialize
异步,现在无法保证在您调用view.render();
initialize
时已完成执行。您必须访问async initialize()
返回的承诺,并在解决后调用render
我不确定是否可能使用主干,因为即使是1.3.3来源也是如此(最新版本afaik)看起来像这样:
var View = Backbone.View = function(options) {
this.cid = _.uniqueId('view');
_.extend(this, _.pick(options, viewOptions));
this._ensureElement();
this.initialize.apply(this, arguments);
// ^----- Does not return the promise,
// and shouldn't because this is supposed to be a constructor
};
你会对老式的
更好collection.fetch().then(this.render.bind(this));
为什么不使用现有的承诺?