节点js:执行所有迭代的函数

时间:2017-07-30 00:01:11

标签: javascript node.js

也许这是一个普遍的问题,我需要一个解决方案来解决我的问题:由于javascript的非阻塞方面,我找不到如何在for循环中执行所有迭代的函数,这里是我的例如,

var text_list=[]
for (var i = 0; i < 10; i++) {
    var element = array[index];
    tesseract.process("img"+i+".jpg", options, function (err, text) {
        if (err) {
            return console.log("An error occured: ", err);
        }
        text_list.push(text)
    });
}
console.log(text_list) //

结果好像我这样做:

tesseract.process("img"+9+".jpg"...
tesseract.process("img"+9+".jpg"...
tesseract.process("img"+9+".jpg"...
.
.
.

我需要的是:

tesseract.process("img"+0+".jpg"...
tesseract.process("img"+1+".jpg"...
tesseract.process("img"+2+".jpg"...
.
.
. 

1 个答案:

答案 0 :(得分:2)

您的问题并没有真正解释您获得的结果,而您的代码似乎缺少代码部分。所以,我能真正帮助的是一般地解释(尽可能使用你的代码)如何解决这类问题。

如果您最终得到的结果都是在循环中引用i的最后一个值,那么您可能尝试在异步回调中引用i,但因为回调是稍后调用,for循环在回调执行之前就已经完成了很久。因此,i的值位于for循环中的最后一个值。但是,您的问题实际上并未显示执行此操作的代码,因此这只是基于您描述的有限结果的猜测。要解决此类问题,请确保为循环的每次迭代分别跟踪i。有很多方法可以做到这一点。在ES6中,在let循环定义中使用for将为您解决整个问题。也可以构造一个闭包,使用.forEach()等......

使用循环进行异步操作需要额外的工作和编码来处理。现代的解决方案是将您的异步操作转换为使用promises,然后使用Promise.all()等功能来告诉您何时完成所有异步操作并按顺序保存结果。

您也可以手动编码而无需承诺。这是一个手册版本:

const len = 10;
let text_list = new Array(10);
let doneCnt = 0;
let errFlag = false;

// using let here so each invocation of the loop gets its own value of i
for (let i = 0; i < len; i++) {
    tesseract.process("img"+i+".jpg", options, function (err, text) {
        if (err) {
            console.log("An error occured: ", err);
            // make sure err is wrapped in error object
            // so you can tell errors in text_list array from values
            if (!(err instanceof Error)) {
                err = new Error(err);
            }
            text_list[i] = err;
            errFlag = true;
        } else {
            text_list[i] = text;
        }
        // see if we're done with all the requests
        if (++doneCnt === len) {
            if (errFlag) {
                // deal with situation where there were some errors
            } else {
                // put code here to process finished text_list array
            }
        }
    });
}
// you can't process results here because async operations are not
// done yet when code here runs

或者,使用promises,你可以制作一个&#34; promisified&#34;版本tesseract.process(),然后使用promise功能跟踪多个异步操作:

// make promisified version of tesseract.process()
tesseract.processP = function(img, options) {
    return new Promise(function(resolve, reject) {
        tesseract.process(img, options, function(err, text) {
            if (err) {
                reject(err)
            } else {
                resolve(text);
            }
        });
    });
}

const len = 10;
let promises = [];
for (let i = 0; i < len; i++) {
    promises.push(tesseract.processP("img"+i+".jpg", options));
}
Promise.all(promises).then(function(results) {
    // process results array here (in order)
}).catch(function(err) {
    // handle error here
});