我正在尝试使用 Q.js
来处理 Web 应用程序中与 promises
和 deferrable
相关的一些问题 - 我将从说我现在对 async
的理解基本上是 0。这是我第一次真正尝试,即使在尽可能多地阅读了文档之后,我还是真的迷失了方向。
我以前使用名为jsdeferred
的库来完成以下代码;它循环遍历文件列表并加载它们,并将它们添加到数组中。但我后来了解到,我不应该使用 jsdeferred
,我被告知我应该改用 promises
和 < em>deferrables
正确。
我为此探索了很多地方,我可能只是愚蠢,但我很难在面向 promise 的库中实现这个确切的代码(在这个例子中,我试图使用 Q .js
,没有成功)。
Q.js Library
define(function () {
return function (selector, callback) {
var files = [
"/app_content/json/ecma5.json",
"/app_content/json/jquery.json",
"/app_content/json/tangent.json"
];
var results = [];
var editor, server;
return Deferred.loop(files.length, function (i) {
return $.get(files[i]).next(function(data) {
results.push(data);
});
}).next(function () {
// a lot of things happen here. they are amazing things.
}).next(function() {
// seriously, this stuff is awesome.
}).next(function() {
callback(editor);
});
};
});
我在文件加载/循环方面遇到了特别困难的时间,我们将不胜感激。我想一旦我在这里站稳脚跟,我就可以更好地进行,但是这个文件循环真的让我失望了。我在文档中一直阅读的所有内容似乎都是针对一次性使用场景的。
我仍在阅读文档,我会继续这样做,但如果有人能帮助我站稳脚跟,我将不胜感激。一旦我看到它与我自己的东西一起工作,我就更容易接受其他情况。我还有大约 20 个其他地方需要开始使用这个概念,但这是第一个让我头疼的地方。
更新
我没有使用Q.js
,它只是最受推荐的一个。我也在看 https://github.com/caolan/async
是否能解决我的问题。
进一步更新
更多地使用文档,我已经合并了一些工作代码,但它似乎仍然缺少一些东西。我无法将 results
作为参数传递给每个 then(fn)
,我必须将其保留为外部变量。
var results = [];
var editor, server;
var chain = files.reduce(function (previous, item) {
return previous.then(function(previousValue) {
return Q.resolve($.get(item, function(data) {
results.push(data);
}));
});
}, Q.resolve());
chain
.then(function (results) {
})
.then(function (results) {
// I can't seem to get results to pass through the 2nd 'next'.
})
.then(function () {
callback(editor);
});
最终结果
在大家的帮助下,我终于让这段代码按我想要的方式工作了。这是最终的结果。这是使用 tern 和自定义脚本定义的 CodeMirror 的实现。
define(function () {
return function (selector, callback) {
var editor, server, results, files = [
"/app_content/json/ecma5.json",
"/app_content/json/jquery.json",
"/app_content/json/tangent.json"
];
Q
.all(files.map($.get))
.then(function(data) {
results = data;
})
.then(function() {
editor = CodeMirror.fromTextArea(selector[0], {
mode: { name: "javascript", globalVars: true },
lineNumbers: true,
lineWrapping: true,
matchBrackets: true,
indentUnit: 2,
tabMode: "spaces",
autoCloseBrackets: true,
matchTags: true,
highlightSelectionMatches: true,
continueComments: "Enter",
foldGutter: true,
width: "100%",
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
extraKeys: {
"Ctrl-Space": "autocomplete",
"Ctrl-Q": function(cm) { cm.foldCode(cm.getCursor()); }
}
});
})
.then(function() {
server = new CodeMirror.TernServer({
defs: results
});
editor.setOption("extraKeys", {
"Ctrl-Space": function(cm) { server.complete(cm); },
"Ctrl-I": function(cm) { server.showType(cm); },
"Alt-.": function(cm) { server.jumpToDef(cm); },
"Alt-,": function(cm) { server.jumpBack(cm); },
"Ctrl-Q": function(cm) { server.rename(cm); },
});
editor.on("cursorActivity", function(cm) { server.updateArgHints(cm); });
})
.then(function() {
callback(editor);
})
.done();
};
});
我非常感谢这里提供的建设性的、有用的、有用的和知识渊博的信息。
最佳答案
使用 Q.js,假设您不需要随请求发送任何数据,您可以使用 map
来缩短代码和 Q.all
:
var results,
files = [
"/app_content/json/ecma5.json",
"/app_content/json/jquery.json",
"/app_content/json/tangent.json"
];
Q.all(files.map($.get))
.then(function(_results) {
results = _results;
})
.then(function () {
// More awesome stuff here
})
.then(function () {
// etc...
console.log(results);
})
.done();
请注意,为了在后续的 .then()
block 中使用 results
,您必须在 promise 链之外保存对它的引用。在您的示例中,您想要的 results
是您传递给 then()
的函数的本地 - 它隐藏了全局 results
。只需给它一个不同的名称,例如 _results
,然后将其分配给全局 results
,以便以后能够使用它。
关于javascript - 尝试使用 Q.js 遍历文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24345076/