有没有人试图让下划线JS或lodash (或任何ES5标准函数)与生成器一起工作?
如果我们有一个数组var myArray = [1,2,3,4,6];
,我们想要对它进行forEach。
在非生成器的情况下,您可以简单地
myArray.forEach(function(k) {
console.log(k);
});
然而,当你不能在非生成器函数中让步时,所以如果在这个循环中我们必须做一些异步工作,你需要做以下的事情。
var foreach = function* (arr, fn) {
var i;
for (i = 0; i < arr.length; i++) {
yield * fn(arr[i], i);
}
};
yield* foreach(myArray, function* (k) {
var a = yield fs.readFile();
});
这太糟糕了。
有人知道让匿名函数与生成器一起工作的方法吗?就因为这个,我们失去了整个lodash图书馆。
注意:我正在使用Traceur将我的代码编译成打开生成器的ES6。
注意:我没有使用co()。我使用的是一个自定义生成器函数,如下所示
var run = function(generatorFunction) {
var generatorItr = generatorFunction(resume);
function resume(callbackValue) {
generatorItr.next(callbackValue);
}
generatorItr.next();
};
发布于 2014-08-05 03:52:36
如果我对你的问题的理解是正确的,那么本质上就是你试图以异步的方式做一些事情(迭代直到找到一个好的停止点),用一种真正围绕同步性设计的语言(JS)。换句话说,虽然您通常可以这样做:
_([1,2,3]).any(function(x) {
var shouldWeStopLooping = x % 2 == 0;
return shouldWeStopLogging;
});
相反,你想让“我们应该停止循环”的代码从正常执行中中断,然后返回,这在传统的JS中是不可能的(yield
对该语言来说是相对较新的),因此在下划线/Lodash中是不可能的:
_([1,2,3]).any(function(x) {
var shouldWeStopLooping = $.ajax(...); // Doesn't work; code keeps going
return shouldWeStopLogging;
});
您可以采用两种方法,但这两种方法都不理想。
正如评论中提到的,一种方法是首先完成所有“延迟”的工作,然后迭代:
var workInProgress = _([1,2,3]).map(someAjaxOperation);
$.when.apply(workInProgress).done(doSomethingBasedOnAjaxResults);
但(在注释中也提到)这并不完全相同,因为您最终会在数组的所有元素上执行AJAX工作(与真正的生成器相比,它只会遍历尽可能多的生成器以找到“赢家”)。
另一种方法是消除异步性。jQuery允许您将async: false
传递给AJAX请求,而AJAX请求则通过使用下划线/大写字母/其他命令来“解决”问题。但是,它也会锁定用户的浏览器,直到它完成AJAX工作,这可能不是您想要的。
不幸的是,如果你想使用下划线/Lodash这样的库,那是我能看到的唯一选择。您唯一的其他选择将是编写您自己的下划线/Lodash混合,这真的不是那么难。我建议这样做,因为这将允许您仍然利用这些库中的所有其他优秀函数,同时仍然以一致的方式迭代。
https://stackoverflow.com/questions/24967314
复制相似问题