Promise 和 setTimeout

2024-06-13

我正在尝试确定一种方法来“暂停”我的 Promises 代码,直到条件成立为止,也许可以使用递归setTimeout()。对于我的简单示例,我手动设置waitValue.

我需要等一下,如果waitValue仍然是错误的,那就只能继续等待了。当然,当waitValue为真,则继续处理。这是我到目前为止拼凑的内容:

var counter=0;
function promiseTest() { 
    return new Promise(  (resolve, reject) => {
        if  ( waitValue )  {
            console.log('waitValue is now true');
            resolve('FIRST PROMISE');
        } else  {                      // we need to wait again
            if  ( counter > 1000 ) {   // dont wait forever.
                reject('waited too long');
            } else {
                console.log('WAIT MESSAGE: ' + counter++ );
                setTimeout( promiseTest, 3000);
            }
        }
    })
    .then(   result => {
        return(`SECOND PROMISE:  the result is: ${result}`);
    });
}

并使用它:

promiseTest().then( (result)=>{ console.log('LOCAL MESSAGE: ' + result); });

以下工作正常:

var waitValue = true;
promiseTest().then( (result)=>{ console.log('LOCAL MESSAGE: ' + result); });
// waitValue is now true
// LOCAL MESSAGE: SECOND PROMISE:  the result is: FIRST PROMISE

但是,以下内容似乎没有按照我想要的方式完成:

var waitValue = false;
promiseTest().then( (result)=>{ console.log('LOCAL MESSAGE: ' + result); });
// waiting messages appear as expected
waitValue = true;
// waitValue is now true
// no other messages

我一直无法找到暂时执行的承诺示例。一个普通的 JavaScript 示例可能如下所示:

var waitValue = false;
var counter = 0;
(function tester() {
   if  ( waitValue ) {
      console.log('finally true');
   } else {
       if  ( counter > 1000 ) {
           console.log('waited too long');
           process.exit;
       } else {
           console.log('still waiting, counter = ' + counter++);
           setTimeout(tester, 1000);
       }
   }
})();
// wait a few seconds and enter this into the console:
var waitValue = false;

暂时暂停执行的 Promise 脚本会是什么样子?或者也许 Promise 根本不应该这样使用?

非常感谢。


这个想法的方向是正确的。当您递归调用该函数时,您只需要解决当前的承诺,否则您当前的承诺将永远不会实现。

但请注意,如果等待时间较长,您将创建一堆承诺。

function promiseTest(counter = 1000) { 
    return new Promise(  (resolve, reject) => {
        if ( waitValue )  {
            console.log('waitValue is now true');
            resolve('FIRST PROMISE');
        } else if  ( counter <= 0 ) {   // dont wait forever.
            reject('waited too long');
        } else {
            console.log('Count down: ' + counter);
            setTimeout( _ => { // make sure to call `resolve` after the nested promise resolved:
                promiseTest(counter-1).then(resolve);
            }, 3000);
        }
    })
    .then(   result => {
        return `SECOND PROMISE:  the result is: ${result}`;
    });
}

var waitValue = false;

promiseTest().then ( result => {
   console.log('done:', result);
});

// schedule the change of the waitValue:
setTimeout(_ => waitValue = true, 4000);

请注意输出如何包含每个已解析的嵌套链式 Promise 的一些痕迹。

选择

我发现对您定义的函数执行递归调用更直观within the Promise构造函数回调,而不是在创建该函数的函数上Promise。这样你就只创建一个承诺,并且避免了Promise 构造函数反模式 https://stackoverflow.com/q/23803743/5459839它存在于您的想法(及其上面的工作版本)中:

function promiseTest(counter = 1000) { 
    return new Promise(  (resolve, reject) => {
        (function loop(counter) {
            if ( waitValue )  {
                console.log('waitValue is now true');
                resolve('FIRST PROMISE');
            } else if  ( counter <= 0 ) {   // dont wait forever.
                reject('waited too long');
            } else {
                console.log('Count down: ' + counter);
                setTimeout( loop.bind(null, counter-1), 3000);
            }
        })(counter); // initial value of count-down
    })
    .then(   result => {
        return `SECOND PROMISE:  the result is: ${result}`;
    });
}

var waitValue = false;

promiseTest().then ( result => {
   console.log('done:', result);
});

// schedule the change of the waitValue:
setTimeout(_ => waitValue = true, 4000);

请注意输出与第一个版本略有不同,这反映出只有一个new涉及承诺

注意:这不是必需的,但我更喜欢从某个值(1000)开始倒数,并将其作为参数传递给执行循环的匿名函数。

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

Promise 和 setTimeout 的相关文章

随机推荐

  • 与 Visual Studio 2010 的静态 libpng 链接

    我正在尝试向我的应用程序添加 PNG 支持 因此我想包含 libpng 我知道它需要 zlib 因此我也下载了它 我进入 png 文件夹 projects vstudio 然后打开解决方案 我编译了它 一切顺利 我将其中的一些标头添加到我的
  • 无法在 VS Code 中导入

    我是 python 新手 一直在使用 VS code 现在我正在研究汤普森采样问题 需要 numpy 和 matplotlib 我已经导入了这两个库 但 VS code 给出了无法导入的错误 我知道我必须使用 PIP 进行安装 并且我已经看
  • var io = require('../..')(server) 做什么?

    我已经构建了该项目https github com Automattic socket io tree master examples chat https github com Automattic socket io tree mast
  • 使用超类创建构建器时,父类无法返回子类的实例[重复]

    这个问题在这里已经有答案了 如果我使用构建器模式来配置新对象 我可能有两个类 例如Game and HockeyGame 如下所示 当我想创建一个新的HockeyGame 我得到它的构建器并开始调用方法来根据需要配置对象 我遇到的问题显示在
  • 从模板绑定到 viewmodel 的属性

    我为我的 GameViewModel 创建了一个视图 我有一些像这样的xaml
  • 如何获取 Grails 应用程序的绝对路径

    我希望用户能够下载我的文件web app images folder 我已经建立了这样的行动 def download def file new File params filepath if file exists response se
  • 多次客户端打印后,Arduino (Uno) 以太网客户端连接失败

    我正在使用带有以太网扩展板的 Arduino Uno 发送多次 HTTP 请求后 客户端 println 客户端连接时开始失败 故障时间似乎是随机的 并且循环中的序列读数可能在 1000 和 7000 之间变化 该错误与以太网发送缓冲区溢出
  • Firebase 托管:部署时缓存清除脚本

    我有一个托管在 firebase 上的聚合物 单页应用程序 应用程序 当我将新版本部署到 firebase 时 我希望 firebase 重新加载 javascript 源而不是使用缓存的源 是否可以通过 firebase json 做到这
  • 在 HTML5 画布上绘制一个点 [重复]

    这个问题在这里已经有答案了 使用以下命令在 HTML5 画布上绘制一条线非常简单context moveTo and context lineTo 功能 我不太确定是否可以绘制一个点 即为单个像素着色 lineTo 函数不会绘制单个像素线
  • AWSS3GetObjectRequest ifModifiedSince 不起作用

    建设为iOS 7 建立在Xcode 6 1 使用亚马逊SDKAWSiOSSDKv2 2 0 12 测试于iPhone 5s 和 iPad 2 我正在使用适用于 iOS 的 Amazon SDK 从我的 Amazon S3 存储桶下载图像 下
  • Android Chronometer 恢复功能

    我尝试使用 Chronometer 在我的 Android 应用程序中创建一个恢复按钮 到目前为止 我有简历方法的代码片段 private long pauseResume long timeWhenStopped chronometer
  • 使用 forEach 循环 Array(n),未定义值的数组[重复]

    这个问题在这里已经有答案了 我想快速构建一个数组n使用数组构造函数的长度Array 然后循环得到的数组 Per MDN 的文档 https developer mozilla org en US docs Web JavaScript Re
  • 基本的 Python OpenCV 裁剪和调整大小

    有人可以帮我一些裁剪算法吗 它的 openCV 我想弄清楚这一点 我知道方法是crop image y y1 x x1 如果我有一个带有 new dimensionXxnew dimensionY 像素的图像 并且我想将其裁剪为相同的宽度
  • 与 CPython、Jython 和 IronPython 相比,PyPy 能提供什么?

    从我在博客上看到和读到的内容来看 PyPy 是一个非常雄心勃勃的项目 与它的兄弟姐妹 CPython Jython 和 IronPython 相比 它会带来哪些优势 是速度 跨平台兼容性 包括移动平台 在没有 GIL 的情况下使用 c 扩展
  • 配置 Restlet 以在 Google App Engine 上返回 JSP?

    我开发了一个 Restlet 应用程序 我想通过 Restlet 返回一个 URL 请求的 JSP 文件 在不使用重定向的情况下如何实现此目的 IE 假设我在 mydomain com 上有文件 contact jsp 并且我希望人们能够访
  • 如何使用 sf::st_centroid 计算多边形的质心?

    我正在尝试使用新的 sf 包在 R 中操作一些巴西人口普查数据 我可以导入数据 但当我尝试创建原始多边形的质心时出现错误 library sf Donwload data filepath lt ftp geoftp ibge gov br
  • 避免 Inno Setup 中的“无法展开 shell 文件夹常量 userdocs”错误

    我将一些示例文档安装到 Windows 上标准 我的文档 文件夹的 PerfectTablePlan 子文件夹中 这对于 99 以上的用户来说效果很好 但是 如果用户没有 我的文档 文件夹 我会收到许多以下形式的丑陋错误消息 内部错误 无法
  • 使用 .Net HttpListener 进行多线程

    我有一个听众 listener new HttpListener listener Prefixes Add http 8077 listener Start listenerThread new Thread HandleRequests
  • 使用“NOT IN”的 LINQ to SQL 查询

    可以使用 LINQ to SQL 查询NOT IN 例如 SELECT au lname 声明 FROM 作者 WHERE 声明 NOT IN CA IN MD List
  • Promise 和 setTimeout

    我正在尝试确定一种方法来 暂停 我的 Promises 代码 直到条件成立为止 也许可以使用递归setTimeout 对于我的简单示例 我手动设置waitValue 我需要等一下 如果waitValue仍然是错误的 那就只能继续等待了 当然