Kap*_*ath 1 javascript jquery nested promise deferred
以下代码负责读取文件.我的要求是如何查找是否已读取所有文件,以便我可以从父函数(readmultifiles)返回或解析promise.
$.when(readmultifiles(files))
.then(function(){//all files uploaded}))
Run Code Online (Sandbox Code Playgroud)
上面的代码启动文件读取.可以做什么,以便在读取所有文件时完成回调或可以返回.
function readmultifiles(files) {
// Read first file
setup_reader(files, 0);
}
function setup_reader(files, i) {
var file = files[i];
var name = file.name;
var reader = new FileReader();
reader.onload = function(e) {
readerLoaded(e, files, i, name);
};
reader.readAsBinaryString(file);
// After reading, read the next file.
}
function readerLoaded(e, files, i, name) {
// get file content
var bin = e.target.result;
// do sth with text
// If there's a file left to load
if (i < files.length - 1) {
// Load the next file
setup_reader(files, i + 1);
}
}
Run Code Online (Sandbox Code Playgroud)
在使用您的实现可以学习的承诺的好设计中,有几件事需要考虑:
readFile().它readFile()在您的项目或未来项目的其他地方也更有用.鉴于这一切,这里有五种方法来实现您的代码 - 使用标准承诺,使用jQuery承诺和您的操作序列或并行运行并使用Bluebird承诺.在所有情况下,您最终都会按顺序获得一系列结果.
readFile()使用标准承诺进行宣传
首先,让我们"宣传"你的readFile操作,这样你就可以使用promise逻辑来控制事物了.
function readFile(file) {
return new Promise(function(resolve, reject) {
var reader = new FileReader();
reader.onload = function(e) {
resolve(e.target.result);
};
reader.onerror = reader.onabort = reject;
reader.readAsBinaryString(file);
});
}
Run Code Online (Sandbox Code Playgroud)
有了标准承诺,所有操作都是并行的
要并行运行所有文件操作并按顺序返回所有结果并使用标准promise,您可以这样做:
function readmultifiles(files) {
return Promise.all(files.map(readFile));
}
// sample usage
readmultifiles(arrayOfFiles).then(function(results) {
// all results in the results array here
});
Run Code Online (Sandbox Code Playgroud)
有了标准承诺,所有操作都按顺序进行
要按顺序运行所有文件操作(这看起来不像你需要在这里执行,因为所有操作都是独立的,即使你的原始代码对它们进行排序)并按顺序返回所有结果并使用标准的promises,你可以做这个.
这种用于排序的标准设计模式用于.reduce()对数组进行排序并将所有操作链接在一起,因此它们在链的序列中一次运行一个:
function readmultifiles(files) {
var results = [];
files.reduce(function(p, file) {
return p.then(function() {
return readFile(file).then(function(data) {
// put this result into the results array
results.push(data);
});
});
}, Promise.resolve()).then(function() {
// make final resolved value be the results array
return results;
});
}
// sample usage
readmultifiles(arrayOfFiles).then(function(results) {
// all results in the results array here
});
Run Code Online (Sandbox Code Playgroud)
而且,这是使用jQuery承诺的样子
readFile()使用jQuery承诺Promisify :
function readFile(file) {
return new $.Deferred(function(def) {
var reader = new FileReader();
reader.onload = function() {
def.resolve(e.target.result);
};
reader.onerror = reader.onabort = def.reject;
reader.readAsBinaryString(file);
}).promise();
}
Run Code Online (Sandbox Code Playgroud)
与jQuery并行运行:
function readmultifiles(files) {
return $.when.apply($, files.map(readFile));
}
// sample usage
readmultifiles(arrayOfFiles).then(function() {
var results = Array.prototype.slice(arguments);
// all results in the results array here
});
Run Code Online (Sandbox Code Playgroud)
并且,与jQuery顺序运行
function readmultifiles(files) {
var results = [];
files.reduce(function(p, file) {
return p.then(function() {
return readFile(file).then(function(data) {
// put this result into the results array
results.push(data);
});
});
}, $.Deferred().resolve()).then(function() {
// make final resolved value be the results array
return results;
});
}
// sample usage
readmultifiles(arrayOfFiles).then(function(results) {
// all results in the results array here
});
Run Code Online (Sandbox Code Playgroud)
蓝鸟实施
而且,为了完整起见,我将向您展示使用像Bluebird这样的更高级的承诺库,它具有在这里有用的附加功能.并行代码和实现与readFile()标准promises相同,但对于顺序实现,它可以利用一些内置的Bluebird操作来对异步操作进行排序,它只包括:
function readmultifiles(files) {
return Promise.mapSeries(files, readFile);
}
// sample usage
readmultifiles(arrayOfFiles).then(function(results) {
// all results in the results array here
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
707 次 |
| 最近记录: |