Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 递归自调用函数和异步操作_Javascript_Asynchronous_Winjs - Fatal编程技术网

Javascript 递归自调用函数和异步操作

Javascript 递归自调用函数和异步操作,javascript,asynchronous,winjs,Javascript,Asynchronous,Winjs,从中,我发现我可以使用forEach循环或自调用来执行异步I/O操作。我不知道为什么它对我不起作用,但是循环部分工作正常,没有调用任何异步函数 var fileNames = ["fileA", "fileB", "fileC", "fileD", "fileE", "fileF", "fileG", "fileH"]; var json; (function parseFiles(i) { console.log(i + " " + fileNames[i]); var

从中,我发现我可以使用
forEach
循环或自调用来执行异步I/O操作。我不知道为什么它对我不起作用,但是循环部分工作正常,没有调用任何异步函数

var fileNames = ["fileA", "fileB", "fileC", "fileD", "fileE", "fileF", "fileG", "fileH"];
var json;

(function parseFiles(i) {

    console.log(i + " " + fileNames[i]);

    var uri = new Windows.Foundation.Uri('ms-appx:///data/' + fileNames[i] + '.json');

    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(function (file) {
        Windows.Storage.FileIO.readTextAsync(file).then(function (contents) {
            json[fileNames[i]] = JSON.parse(contents);

            if (i < fileNames.length) {
                parseFiles(i+1);
            } else {}
        });
    });

})(0);
这里有两个问题:

  • 如何修复它,使其从一个文件转到另一个文件
  • 解析文件后,我是将代码放在自调用函数之后的变量
    json
    中,还是放在
    readFileAsync()
    返回的承诺的
    then
    函数的
    循环中
  • 我最终做了这样的事:

    var fileNames = ["fileA", "fileB", "fileC", "fileD", "fileE", "fileF", "fileG", "fileH"];
    var json;
    
    (function parseFiles() {
    
        var name = fileNames.pop();
    
        Windows.Storage.StorageFile.getFileFromApplicationUriAsync(new Windows.Foundation.Uri('ms-appx:///data/' + name + '.json'))
            .then(function (file) {
                return Windows.Storage.FileIO.readTextAsync(file);
            }, function error(e){
                console.dir(e);
            })
            .then(function (contents) {
                json[name] = JSON.parse(contents);
            })
            .then(function () {
                console.log("Name: "+name+" Remaining array length:"+fileNames.length);
    
                if (fileNames.length === 0) {
                    console.log('all done');
                    // do whatever else here
                } else {
                    parseFiles();
                }
            });
    })();
    

    我很高兴递归函数中的异步方法使用Promise接口,这样我就不必编写一大堆递归函数。

    如果在异步函数中
    I
    ,则可能应该将其移动到外部函数,并传入文件名。但这并不能确保函数按顺序完成,您需要使它们同步才能做到这一点。@RobG显然您错了。异步调用中的增量是执行此操作的全部要点。代码是正确的,请参阅下面的JSFIDLE:我已将异步调用替换为setTimeout。从输出来看,这个函数似乎同时被调用了两次。错误在别的地方。
    var fileNames = ["fileA", "fileB", "fileC", "fileD", "fileE", "fileF", "fileG", "fileH"];
    var json;
    
    (function parseFiles() {
    
        var name = fileNames.pop();
    
        Windows.Storage.StorageFile.getFileFromApplicationUriAsync(new Windows.Foundation.Uri('ms-appx:///data/' + name + '.json'))
            .then(function (file) {
                return Windows.Storage.FileIO.readTextAsync(file);
            }, function error(e){
                console.dir(e);
            })
            .then(function (contents) {
                json[name] = JSON.parse(contents);
            })
            .then(function () {
                console.log("Name: "+name+" Remaining array length:"+fileNames.length);
    
                if (fileNames.length === 0) {
                    console.log('all done');
                    // do whatever else here
                } else {
                    parseFiles();
                }
            });
    })();