链接 2 个异步调用(promise API)以串行运行

2024-01-28

这与我发布的问题类似today https://stackoverflow.com/questions/16307652/promise-api-combining-results-of-2-asynchronous-call,但需要串行链接请求。我有两个异步请求,其中第二个请求需要第一个请求的结果来发送查询。

var Db.get = function(key){
    var deferred = $q.defer();

     //send async req
    var req = ....
    req.success = function(d){
        deferred.resolve(d)
    };
    req.failure = function(d){
        deferred.reject(d)
    }

    return deferred.promise;
}

var someFn = function(id){
    Db.get(id, "abc")
        .then(function (d) {
            console.log("At 1")
            Db.get(d.id, "def")
                .then(function (d) {
                    console.log("At 2")
                    return d
                }, function (e) {
                    //error
                });
        }, function (e) {
            //error
        });

    console.log("At 3")
};

正如我所料,我应该想错了console.log("At 3")当我返回后,永远不会在成功场景中打印console.log("At 2")。但是当我运行时,在控制台中我看到这些顺序

console.log("At 1")
console.log("At 3")
console.log("At 2")

我刚在想then会阻塞,直到它得到 Promise 的响应(由 get() 返回)。因此,someFn 中的所有内容都是串行执行的。这个假设是错误的吗?链接两个使用 Promise 的异步操作以串行运行的最佳方法是什么。

Thanks.

EDIT:

我尝试了 Ketan 的建议在 AngularJs 中链接 Ajax 调用 https://stackoverflow.com/questions/16284403/chaining-ajax-calls-in-angularjs .

var someFn = function(id){
            Db.get(id, "abc")
                .then(function (d) {
                    console.log("At 1")
                    return Db.get(d.id, "def")
                }).then(function (d) {
                    console.log("At 2")
                    return d
                }, function (e) {
                    //error
                    return null;
                }).then(function (d) {
                    return d;
        });

        console.log("At 3")
    };

不过,如果我拨打这样的电话

var res = someFn(1)
console.log(res) /// undefined

镀铬终端显示At 2 after undefined。我不确定为什么返回结果someFn未分配给res.


你遇到困难的地方是.then实际上并没有阻止。它可以帮助您将同步代码转换为异步代码,但它不会为您这样做。让我们首先考虑您尝试重写的同步代码。想象Db.get是一个返回值而不是承诺的同步函数:

var someFn = function (id){
    try {
        var d = Db.get(id, "abc");
        console.log("At 1");
        var d = Db.get(d.id, "def");
        console.log("At 2")
        return d;
    } catch (ex) {
        console.log("At 3")
    }
};

在这种情况下,当我打电话时someFn我得到的是一个价值,而不是一个承诺。也就是说整个功能是同步的。

如果我们暂时快进几年并想象我们可以使用 ES6。这将使我们将您的函数重写为:

var someFn = $q.async(function* (id){
    try {
        var d = yield Db.get(id, "abc");
        console.log("At 1");
        var d = yield Db.get(d.id, "def");
        console.log("At 2")
        return d;
    } catch (ex) {
        console.log("At 3")
    }
});

看起来很相似,但这次我们有Db.get返回一个承诺,并且someFn()也总是会返回一个承诺。这yield关键字实际上“暂停”当前函数,直到履行承诺。这让它看起来就像同步代码,但实际上是异步的。

回到现在,我们需要弄清楚如何写这个。 a 的第二个参数.thencall 是一个错误处理程序,因此与 ES6 示例完全相同:

var someFn = function (id){
    return Db.get(id, "abc")
        .then(function (d) {
            console.log("At 1");
            return Db.get(d.id, "def");
        })
        .then(function (d) {
            console.log("At 2");
            return d;
        })
        .then(null, function (ex) {
            console.log("At 3")
        });
});

请注意每个返回如何仅从其当前函数范围返回。没有办法强迫它一路跳出来someFn.

另一个有趣的实验是:

Db.get('id', 'abc')
  .then(function () {
    console.log('B');
  });
console.log('A');

上面的内容总是会记录:

A
B

because .then不阻止。

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

链接 2 个异步调用(promise API)以串行运行 的相关文章

  • Jest 中从未调用图像 onLoad 处理程序

    我正在尝试使用 Jest 测试将 dataUrl 加载到图像中 我正在使用 JSDOM 并按照说明添加resources usable 作为一个选项 如果我直接从 Node 运行该代码 则该代码可以工作 但是当我尝试在 Jest 中运行它时
  • 尝试使用 angularJS 和 c# webapi 从服务器下载文件

    将文件上传到服务器时效果很好 没有损坏的文件 但是 当我下载文件时 除了纯txt 它们起作用 它们的规模不断扩大并变得腐败 经过大量调查后 我不知道可能出了什么问题 我只是写文件 作为响应流并下载 blob 欢迎任何想法 严重依赖此线程来解
  • Vue js按钮冻结dom

    我试图在按下按钮时切换包含加载动画的跨度 直到使用 v if 函数完成 但是当我按下按钮时 DOM 冻结并且 span 元素保持不变 直到函数调用结束 如何让 DOM 不冻结并显示加载图标 非阻塞按钮按下可能是一个解决方案 HTML
  • 将字符串转换为变量名。 (JavaScript)

    我确实查看了前面的问题 但它们是针对整数值的 我需要文本值的答案 我在本周早些时候问了一个与此相关的问题 但现在是这样 如下所示 我使 Make x 等于某个字符串值 Acura Honda Toyota 当我将 Make x 传递到函数
  • IE8 中的 Javascript 消息超出堆栈空间

    我正在使用 Breeze 1 4 1 Internet Explorer 8 和 ASP NET MVC 4 Web API 我在查询时收到以下消息 查询失败 localhost port breeze Data Metadata 元数据导
  • Angular 7 Guard 重定向仅适用于双击

    问题是我已经实现了一个 Guard 旨在处理特定的目录 如果当前用户名的角色等于 2 它应该返回 true 如果没有 那么它不应该重定向 这是我的 app routing module ts 文件 问题出在 userlist 路径中 我们是
  • AttachEvent 或 addEventListener - 存储在哪里?

    在 jQuery 中 如果我这样做 a click function Do something 点击事件存储在 a data events 我可以像这样获取它 jQuery each a data events function i eve
  • perl:正确的“内容类型”格式以返回“图像数据 uri”

    我有一个模板angularjs期待着image data uri由通过调用的服务器调用返回src的属性img模板的元素 img width 200px height 200px src http localhost 3000 returni
  • 在社交媒体 Ruby On Rails 上共享链接时的小预览

    我正在开发一个前端位于的网站angularjs和后端ROR Same ROR API用于android app还 现在我这里有一个情况 我需要在社交媒体上分享我的网站帖子 例如facebook twitter and google plus
  • 如何正确关闭 Node.js Express 服务器?

    我需要在收到回调后关闭服务器 auth github callback网址 与平常一样HTTP API http nodejs org docs latest api http html关闭 服务器目前支持server close call
  • Angular UI.Bootstrap 单选按钮在 ng-repeat 中表现得很奇怪[重复]

    这个问题在这里已经有答案了 我在 Angular 的 ui bootstrap 中动态生成无线电模型的选项时遇到问题 我想我可以简单地对数组进行 ng repeat 使用 btn radio 属性的内容 如下所示 in the contro
  • 通过电子邮件发送在 HTML5 画布上创建的图像

    我有一个画布 用户可以通过交互来更改设计 现在 用户完成更改后 可以提交他的设计及其电子邮件 ID 但为了提交设计 我使用以下方法将画布转换为图像http www nihilogic dk labs canvas2image http ww
  • Google Maps JS Api - b.get 不是函数错误(isLocationOnEdge)

    我想检查我的路线上是否有标记 所以我尝试使用 isLocationOnEdge 但收到 TypeError b get 不是函数 错误 这是我的代码 我尝试了几次更改但无法解决问题 var directionsDisplay new goo
  • Django 模板变量从 {% for %} 循环到 Javascript

    这是一个迭代记录的 Django 模板 每条记录都包含一个由 JS 函数填充的 div 为了让 JS 知道要做什么 它需要从每次 for 循环迭代中获取一个变量并使用它 我不知道具体如何实现这一目标或是否可能 我不知道 也许记录在单独的 J
  • 如何混淆或使 JavaScript 文件不可读?

    我的应用程序中有 JavaScript 脚本 其中包含 JavaScript 和 jQuery 函数 所有用户与我的应用程序的交互都是动态的 并且通过 jQuery 传递到应用程序 我意识到 当我在客户端运行我的应用程序时 客户端可以通过查
  • jQuery live() 和ready() 之间的区别?

    两者之间的确切区别是什么live and ready 编辑 发现die http docs jquery com Events die是相反的live ready http docs jquery com Events ready让你注册一
  • 如何从普通 JavaScript 中的输入获取对象

    例如 我有 3 个输入
  • Node.js - Async.js:并行执行如何工作?

    我想知道 async js 中并行执行是如何工作的 async require async async parallel function callback for var i 0 i lt 1000000000 i Do nothing
  • 如何让无限滚动发挥作用?

    我正在尝试让这个无限加载脚本在我的项目中工作 这是我的 HTML div div div class pagina div div class pagina div div class pagina div div class pagina
  • NodeJS 中的缩进多行日志记录

    我要打印JSON stringify d 反对控制台 将上下文作为 Mocha 测试套件输出的一部分 当测试缩进时 我希望对象日志行向右缩进足够远 例如 3 4 个制表符空格 以便它们可以识别地位于右侧describe group 我怎样才

随机推荐

  • PullToRefreshListView$InternalListViewSDK9 中的 IllegalStateException

    我在应用程序的两个活动中使用 PullToRefresh 库 我知道 这个库已被弃用 但它非常有用 它不仅可以处理来自顶部的刷新手势 还可以处理来自底部的刷新手势 但它有一个问题 应用程序很少因以下日志而崩溃 java lang Illeg
  • 如何在 Java 中格式化字符串

    原始问题 但如何格式化这样的字符串 第 1 步 共 2 步 通过使用 Java 替换变量 在 C 中这很容易 看一眼字符串格式 http download oracle com javase 6 docs api java lang Str
  • 将 float 转换或转换为 nvarchar?

    我需要从数据类型 float 的一列中进行选择 并将其作为 nvarchar 插入到另一列中 我尝试投射它 cast Column Name as nvarchar 50 结果是9 07235e 009而不是 10 位数字 电话号码 有谁知
  • Java 中覆盖方法的更广泛的参数类型

    下面的代码破坏了什么面向对象原则 不是 Java OO 原则 而是通用 OO 原则 class GeneralArg class Arg extends GeneralArg class A public void test Arg a c
  • 如何从数据库服务器插入带有时间戳的 MongoDB 文档

    在 Oracle 中 我可以简单地这样做 INSERT INTO myTable VALUES someValue SYSTIMESTAMP 这会将两个值插入到 myTable 中 其中之一是基于数据库服务器时间的时间戳 对于 MongoD
  • Grails 挂在命令行上

    我刚刚下载了 Grails 2 0 1 创建了一个新项目 然后尝试按照文档添加 mysql 连接器 但 Grails 在命令提示符下挂起 没有任何消息 我尝试以详细和堆栈跟踪模式执行 但它什么也没打印 我尝试清理并重新执行 但所有 grai
  • Jenkins Pipelines:如何从共享变量脚本使用 withCredentials()

    我想用一个withCredentials 块在共享变量 vars 脚本中而不是直接在 Jenkins 管道中 因为这是特定库的较低级别语义 并且根据具体情况可能需要也可能不需要 然而 withCredentials 或者 至少 它的签名 似
  • 如何在 OpenCV + Visual C++ 中测量对比度

    以前的问题是 如何在 OpenCV 中选择最佳对比度的图像 但根据 Rook 的建议 我正在更改它 我将在我的项目中使用 OpenCV Visual Studio 2010 我只是想知道 OpenCV 如何让这对我来说更容易 我从视频中提取
  • SQL Server - 缺少索引 - 什么会使用索引?

    我正在使用 SQL Server 2008 我们正在使用 DMV 来查找丢失的索引 然而 在创建新索引之前 我试图找出哪个 proc query 需要该索引 我想要获得最多的信息 以便我可以对我的索引做出明智的决定 有时 SQL Serve
  • 将 List 转换为分隔字符串列表 [重复]

    这个问题在这里已经有答案了 可能的重复 从 List 返回字符串的最优雅的方式 https stackoverflow com questions 1334072 most elegant way to return a string fr
  • OpenCV Android 使用最大轮廓的边缘创建新图像

    我能够检测图像中最大的正方形 矩形 绿色 但是 我想将图像中检测到的最大正方形 矩形转换为新图像 存储在新的 Mat 中 这是该函数的返回图像 其上有最大的矩形 正方形 http img153 imageshack us img153 93
  • NodeJS 从后台进程读取 stdin

    我有一个在 Ubuntu 12 04 LTS 下作为服务运行的节点进程 它在 etc init 下有一个配置文件 该系统在连接了条形码阅读器的无头 x86 路由器板上运行 我需要做的是能够读取来自条形码阅读器的输入 其行为类似于 USB 键
  • 在 .NET Core 中使用 SHA-1

    在 dotnet core 中对字符串进行哈希处理时 我得到了奇怪的结果 我发现了这个类似的问题 使用 ASP NET Core 计算 SHA1 https stackoverflow com questions 35363358 comp
  • sqlite,从另一个表中的列更新列

    我目前正在处理更新的查询table1 state从数据中table2 state基于两个表中的城市字段 换句话说 当表 1 和表 2 中的城市字段匹配时 用表 2 中的州更新表 1 我遇到的问题是 当没有城市匹配时 会随机添加一个州 例如爱
  • 真的需要通配符泛型吗?

    例如 public String add Set gt 这是一个列表的列表 该方法可以向其中添加不同组件类型的列表 public void foo List
  • 在后台脚本中设置间隔

    我正在为实时产品开发浏览器扩展 我有一个在manifest json 中设置了 persistent true 的背景页面 我使用的是v2 版本 我使用 setInterval 每秒不断地轮询服务器以获取新数据 后台脚本还会缓存迄今为止收集
  • 使用纯 R 通过 dbplyr 处理日期

    dbplyr 将 dplyr 和基本 R 命令转换为 SQL 以便开发人员可以编写 R 代码并在数据库中执行它 整洁宇宙参考 https dbplyr tidyverse org 在 R 中处理日期时 通常使用 lubridate 包 然而
  • JDK 11 + JUnit 5 + Jigsaw:Junit 无法运行“模块信息”测试

    我尝试在 Gradle 项目中使用 JUnit 5 compileJava and compileTestJava两者都成功了 但是test失败并显示奇怪的消息Could not execute test class module info
  • 从“dragmove”回调中移动图层后,事件丢失

    我有一个移动图层的滚动条 因此该图层在滚动条的 dragmove 回调中移动 这会导致所有绑定事件在移动的图层上断开连接 请看这个小提琴 http jsfiddle net NY4QK 10 http jsfiddle net NY4QK
  • 链接 2 个异步调用(promise API)以串行运行

    这与我发布的问题类似today https stackoverflow com questions 16307652 promise api combining results of 2 asynchronous call 但需要串行链接请