JS 在循环内等待回调完成

2024-01-14

我的 Node js 应用程序中有一个 for 循环;在此循环内,每次迭代都可以执行 mysql 查询(并非总是如此,具体取决于情况);查询是异步的,我在成功回调中得到结果;但我需要 for 循环的每次迭代都等待回调完成(如果需要):

function calculate() {
    var resArray = [];

    //[...]

    for (i = 0; i < tables.length; i++) {
        if (id !== undefined) {
            var queryString = ...  //build query
            sequelize.query(queryString).success(function(result) {   //executes query
                id = result[0].id;

                //do stuff with id returned by the query
                //...
                //resArray.push( //push in resArray the result of stuff done above )
            });  
       }
       else {
           //do other kind of stuff and push result in resArray
       }
   }
   return resArray;
}

如果 id != undefined,则执行查询,但 for 循环不会等待成功回调,并且函数返回不完整的 resArray。

我该如何做(或者如何重新组织代码)才能完成这项工作? (我正在使用 Node js,但无法使用 jQuery)。


感谢 Amadan 的建议,我使用混合方法(使用 Promise 和 Counter)摆脱了这个问题;

我真的很想知道您对此的看法以及您是否有改进的建议;

首先,我向项目添加了 q 库(npm install q)以使用 Promise。 感谢 q 我已经能够将sequelize.query(基于回调)包装在返回承诺的函数中; Promise 计数器在内存中保存仍待处理的 Promise 数量,并且当每个 Promise 得到解决时,包装函数executeQuery 会递减它;

(cycle()函数中的for循环执行4次循环;执行2次查询和2次简单日志; 目标是只有在 for 循环结束并且所有承诺都得到解决后,“完成”日志才会发送到屏幕

var id = req.params.id;
var counter = 0;
var endCycle = false;

var queryString = 'SELECT * FROM offers WHERE id = ' + id;

function query () {
    var deferred = Q.defer();
    sequelize.query(queryString).success(function(result) {
        console.log('obtained result');
        deferred.resolve(result);
    });
    return deferred.promise;
}

function executeQuery() {
    query().then(function() {
        console.log('after');
        counter --;
        console.log(counter);
        finished();
    });
}

function finished() {
    if ((counter === 0) && (endCycle)) {
        console.log('finished');
        endCycle = false;
    }
}

function cycle() {
    var result;

    for (i = 0; i <= 3; i ++) {
        if (i > 1) {
            counter ++;
            executeQuery();
        }
        else {
            console.log('else');
        }
    }

    endCycle = true;
    finished();
}

cycle();

- - - - - - - - - 更新 - - - - - - - - - - - - - - - - ----------------------------

根据hugomg的建议,我用更干净的代码更新了代码: 我将每个承诺推送到一个数组中,然后使用 Q.all 等待所有承诺都得到解决

var id = req.params.id;
var promisesArray = [];
var endCycle = false;

var queryString = 'SELECT * FROM offers WHERE id = ' + id;
function query () {
    var deferred = Q.defer();
    sequelize.query(queryString).success(function(result) {
        console.log('obtained result');
        deferred.resolve(result);
        finished();
    });
    promisesArray.push(deferred.promise);
}

function finished() {
    if (endCycle) {
        endCycle = false;
        Q.all(promisesArray).then(function() {
            console.log('finished');
        });            
    }
}

function cycle() {
    var result;

    for (i = 0; i <= 3; i ++) {
        if (i > 1) {
            query();
        }
        else {
            console.log('else');
        }
    }
    endCycle = true;
    finished();
}

cycle();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JS 在循环内等待回调完成 的相关文章

随机推荐

  • Prolog 中的简单图搜索

    我正在尝试在 SWI Prolog 中编写一个简单的图形搜索代码 我想出了以下程序 adjacent 1 4 adjacent 4 2 adjacent 3 6 adjacent 6 4 adjacent 7 10 adjacent 4 9
  • 如何正确地与反应形式进行双向绑定?

    到目前为止 我一直认为你不应该混合使用 ngModel 与反应形式 而不是简单地使用formControlName 然而 对我来说 这似乎不起作用 我有一个表单并向其中添加控件 this exportForm addControl surc
  • 如果字段为空,则通过 jQuery 禁用发送按钮

    如果有一个或多个输入字段为空 如何禁用发送按钮 我在伪代码中的尝试 if input empty input disabled else enable the ask question button 我一直在阅读这些文章但没有找到正确的解决
  • 在 Swift 中包含 C++ 头文件

    我有一个 C 头文件 名为header h 我想将其包含到我的 Swift 项目中 由于我想要包含的 C 框架尚未完成 所以我现在只有头文件 我的 C 头文件header h看起来有点像这样 include
  • 在两个 tomcat 服务器上的两个应用程序之间保持 JSP 会话处于活动状态

    您好 我想在 2 个 tomcat 服务器上运行的两个不同应用程序之间保持相同的会话 我在一台服务器上运行一个应用程序 在登录时为其创建一个会话 如果我单击应用程序上的链接 它将被重定向到另一个 tomcat 服务器上的第二个应用程序 此时
  • Bootstrap:模态上的弹出窗口

    我想使用 Twitter 的 Bootstrap CSS 库在现有模态对话框上使用弹出窗口效果 我将弹出框绑定到小图像图标 infoIcon popover offset 50 placement right 模态本身也是根据文档添加的 m
  • Python 列表中的 Numpy.Array?

    我有一个 numpy 数组列表 用作堆栈 现在我想检查数组是否已在列表中 例如 如果它是元组 我会简单地写一些相当于 1 1 in 1 1 2 2 然而 这不适用于 numpy 数组 np array 1 1 in np array 1 1
  • 将元数据添加到 Stripe 客户对象

    我正在使用 Stripe 设置支付系统 我想向客户对象添加一些元数据 我想将我的工作区 ID 添加到客户的元数据属性中 我尝试了下面的代码 但它返回以下错误 Error Error Invalid val bsontype gt Objec
  • 具有在编译时评估的向量的构建器模式(使用“consteval”)

    我正在尝试创建一个遵循构建器模式并且在编译时完全运行的类 使用新的constevalC 20 中的关键字 但无论我尝试什么都不起作用 例如 这是行不通的 include
  • 无法将 json 转换为模型

    我有来自 url 的 json 我需要将此 json 转换为模型 someField 3 datesField 2017 08 19 2017 08 20 2017 08 26 2018 12 30 我创建用于映射的模型 Data NoAr
  • 为什么我的迷宫解算器不起作用?

    我正在尝试编写一个程序 以递归方式解决特定输入的迷宫 并在每次移动后输出它在迷宫中的位置 每当我尝试运行代码时 它都会立即崩溃 并收到 maze exe 已停止工作 错误 为什么我的代码不起作用 include
  • 我可以将多个 Android 密钥库文件合并为一个吗?

    我在使用 Android 密钥库文件时遇到了一个有点烦人的情况 目前 我有几个不同的应用程序 每个应用程序都使用不同的密钥库文件进行签名 有点像这样 使用 AppName1 keystore 签名的 AppName1 apk 使用 AppN
  • Android onItemClicklistener 在列表视图中不起作用

    谁能帮我解决我的问题 我有一个 TabActivity 每个选项卡在触摸时都会打开一个新的活动 该活动扩展了 ListActivity 此时我得到了所需项目的列表 我想通过使用 OnItemClickListener 使其可点击 我正在附上
  • 使用 bash、sed 或 awk 拆分 CSV 文件并排除输出中的列

    我有一个 CSV 文件 其中包含如下数据 1 275 275 17 3 0 2011 05 09 20 21 45 2 279 279 17 3 0 2011 05 10 20 21 52 3 276 276 17 3 0 2011 05
  • 如何在 vscode 中将 .ipynb 作为常规文本而不是 IPython 笔记本查看

    VS Code 最近添加了使用 Jupyter Notebooks 的功能 ipynb文件 这就是说它将它们呈现为笔记本而不是底层文本 我遇到的问题是我想对原始文本而不是 笔记本 进行一些编辑 但我不知道如何像其他编辑器那样将其显示为文本文
  • git push -f 与 +

    这样做有什么区别 git push f origin my branch my branch and git push origin my branch my branch 这是实现同一目标的两种语法 除了那个git push force当
  • 我可以从视图调用模型吗?

    我没有使用成熟的 PHP MVC 而是设计了一个最适合我的用途的 MVC 我已经完成了基本框架 并编写了运行网站所需的模型和控制器 现在我正在转向视图 我遇到了一个小困境 我的方法对我来说效果很好 但为了将来的参考 我想知道我所做的是否是一
  • Django 的 CreateView 不保存对象

    我正在练习 Django 的通用视图 特别是ModelForms 这些是我的观点和模型 模型 py class Post models Model user models ForeignKey User post title models
  • 为什么我使用kill -0 (|pid) 得到不同的结果

    我正在编写一个脚本 该脚本将启动另一个进程 并在一段时间后杀死它 如果它没有自行退出 自从开始这件事以来 我开始意识到timeout命令是执行此操作的正确方法 但我仍然对为什么我的方法之一失败感到困惑 这就是我正在尝试的 bin bash
  • JS 在循环内等待回调完成

    我的 Node js 应用程序中有一个 for 循环 在此循环内 每次迭代都可以执行 mysql 查询 并非总是如此 具体取决于情况 查询是异步的 我在成功回调中得到结果 但我需要 for 循环的每次迭代都等待回调完成 如果需要 funct