Nodejs中正确处理for循环中的异步回调事件。

发布于 1周前 作者 yuanlaile 来自 nodejs/Nestjs

Nodejs中正确处理for循环中的异步回调事件。

标准而又安全的做法,可以参考如下我的code

首先定义一个空的数组,和一个长度
var buffer = [],lens = results1.length;//lens就是你的数组的长度

var telephone = results[0];
var data='';
for( i = 1; i < results1.length; i++) {

一般for的标准是:for(var i=0,len=results1.length;i<len; i += 1){

主要的代码是,用一个自执行的function,以避免每次执行的for中的i值是一个个的,而不是最后一个。像这样的:

    (function(接受的第一个参数,接受的第二个参数){
    在这里面执行你的查询

})(传入第一个参数一般是每一个i的值比如:results1[i],传入第二个参数比如:i);

var recto=telephone.substr(0,7);

    (function(result,l){

      mobileModel.Mobile.findOne({'YJPhone':recto},function(err,mresult){
         if(mresult){
              data+=recto;
            查询成功之后执行
            buffer.push(l); 不管buffer中的内容是什么,只管它的长度,如果执行完了所有的
            if(buffer.length === lens){ 这个lens有可能不是results1的长度,因为可以下面的
                                        else执行了,如果一共查到5条匹配的,总共10条。那么
                                        此时的lens就是5.这样buffer的长度也是5的时候就发送。
                执行最后的发送
                res.send(data);
            }
         }else{ 
            查询不到就改变lens的长度
            lens--;
         }
      }

    })(results1[i],i);

}


5 回复

Node.js 中正确处理 for 循环中的异步回调事件

在 Node.js 中处理异步操作时,特别是在 for 循环中使用异步回调函数时,常常会遇到一些常见的问题,例如并发执行导致的变量作用域问题。本文将介绍一种常用且安全的方法来处理这种情况。

示例代码

假设我们有一个数组 results1,我们需要对每个元素执行一个异步操作,并在所有操作完成后发送结果。

const mobileModel = require('./mobileModel'); // 假设这是你的数据库模型

// 初始化变量
var buffer = [];
var lens = results1.length;

var telephone = results1[0]; // 假设 results 是一个包含初始数据的数组
var data = '';

// 使用 for 循环遍历数组
for (let i = 1; i < results1.length; i++) {
    (function(i) {
        const recto = telephone.substr(0, 7);

        mobileModel.Mobile.findOne({ 'YJPhone': recto }, function(err, mresult) {
            if (mresult) {
                data += recto;

                // 将当前索引推入缓冲区
                buffer.push(i);

                // 检查是否所有异步操作已完成
                if (buffer.length === lens) {
                    // 所有操作完成,发送结果
                    res.send(data);
                }
            } else {
                // 如果查询失败,减少 lens 的长度
                lens--;
            }
        });
    })(i);
}

解释

  1. 变量作用域

    • 为了防止 for 循环中的 i 变量在异步回调中被覆盖,我们使用了一个立即执行函数表达式(IIFE)来创建一个新的作用域。这样每次循环迭代都会创建一个新的 i 变量副本。
  2. 异步操作

    • 在每次循环迭代中,我们调用 mobileModel.Mobile.findOne 方法来执行异步查询。当查询完成时,我们将结果添加到 data 字符串中,并将当前索引 i 推入 buffer 数组中。
  3. 完成检查

    • 我们通过检查 buffer.length 是否等于 lens 来判断所有异步操作是否已经完成。如果完成了,则发送最终的结果。

这种方法确保了每个异步操作都能独立地执行,并且在所有操作完成后能够正确地处理结果。


同样的内容,我本打算回复别人的topic,可为什么说我写的内容Forbibden呢。禁止我回复了?

貌似有在贴吧问过这个问题吧

谢谢…你的回复…

为了正确处理 for 循环中的异步回调事件,我们需要确保每个异步操作都能独立完成,并且不会互相干扰。一种常见的方法是使用立即调用函数表达式(IIFE)来捕获当前循环变量的值。以下是一个具体的例子:

示例代码

const mobileModel = require('./models/mobileModel'); // 假设这是你的模型文件

let buffer = [];
let lens = results1.length;
let telephone = results[0];
let data = '';

for (let i = 1; i < results1.length; i++) {
  (function(i) {
    let recto = telephone.substr(0, 7);

    mobileModel.Mobile.findOne({ 'YJPhone': recto }, function(err, mresult) {
      if (mresult) {
        data += recto;

        // 将当前索引推入缓冲区
        buffer.push(i);

        // 检查是否所有异步操作都已完成
        if (buffer.length === lens) {
          res.send(data);
        }
      } else {
        lens--;
      }
    });
  })(i);
}

解释

  1. 立即调用函数表达式 (IIFE):

    • 使用 IIFE (function(i) { ... })(i); 来捕获当前循环变量 i 的值。这确保了每次迭代中的 i 是独立的,而不是每次都指向最后一个值。
  2. 异步操作:

    • mobileModel.Mobile.findOne 回调中处理异步操作。当查询成功时,将结果数据存储到 data 中,并将当前索引 i 推入 buffer 数组。
  3. 检查操作完成:

    • buffer 的长度等于初始长度 lens 时,说明所有异步操作都已完成,此时发送最终结果 res.send(data)

通过这种方式,我们可以确保在 for 循环中正确处理异步操作,而不会导致意外的结果。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!