JavaScript: Async Promise “while loop”

This is a solution to the situation where you have an asynchronous task you want to perform over and over again, in a non-blocking fashion, stopping when some condition is met.

To set the stage, I’ll be using the Bluebird Promise library, the best Promise library I’ve used.

First, we’ll construct the Promise function which will do the looping:

var Promise = require(‘bluebird‘);

var promiseWhile = function(condition, action) {
    var resolver = Promise.defer();

    var loop = function() {
        if (!condition()) return resolver.resolve();
        return Promise.cast(action())
            .then(loop)
            .catch(resolver.reject);
    };

    process.nextTick(loop);

    return resolver.promise;
};

It receives 2 arguments, both expected to be functions:

  1. condition - This is a predicate function which shall return true or false and indicate whether the end state has been reached. true if done, falseotherwise.
  2. action - This is the async task to be performed, which itself should return a Promise.

A couple things to note:

  • I simulated the async task with a simple setTimeout but this would be optimal for looping over Database calls, HTTP requests, or anything else requiring latency.
  • We use a function for the condition which allows us to do any manner of interesting tests for completion.
  • We utilize process.nextTick to wait until the next CPU cycle before starting. If we don’t do this, it will complete immediately and will not “loop.”
  • You’ll see it is actually using recursion for the iteration, but behaves like a while loop hence the title with the word “while loop” in quotes. But it does follow a while loop-esque format of condition, action, looping until condition is met.

What follows is a sample usage of the promiseWhile() function.

// And below is a sample usage of this promiseWhile function
var sum = 0,
    stop = 10;

promiseWhile(function() {
    // Condition for stopping
    return sum < stop;
}, function() {
    // Action to run, should return a promise
    return new Promise(function(resolve, reject) {
        // Arbitrary 250ms async method to simulate async process
        // In real usage it could just be a normal async event that
        // returns a Promise.
        setTimeout(function() {
            sum++;
            // Print out the sum thus far to show progress
            console.log(sum);
            resolve();
        }, 250);
    });
}).then(function() {
    // Notice we can chain it because it‘s a Promise,
    // this will run after completion of the promiseWhile Promise!
    console.log("Done");
});

And that’s it!

I threw the whole gist on GitHub

Feel free to email me or Tweet me @victorquinn with any questions!

时间: 2024-10-17 13:51:44

JavaScript: Async Promise “while loop”的相关文章

全面理解Javascript中Promise

全面理解Javascript中Promise 最近在学习Promise的时候,在网上收集了一些资料,发现很多的知识点不够系统,所以小编特意为大家整理了一些自认为 比较好的文章,供大家更好地学习js中非常有趣的Promise Promise概念 2015 年 6 月,ECMAScript 6 的正式版 终于发布了. ECMAScript 是 JavaScript 语言的国际标准,javascript 是 ECMAScript 的实现.ES6 的目标,是使得 JavaScript 语言可以用来编写大

异步JavaScript与Promise

异步? 我在很多地方都看到过 异步(Asynchronous)这个词,但在我还不是很理解这个概念的时候,却发现自己常常会被当做"已经很清楚"(* ̄? ̄). 如果你也有类似的情况,没关系,搜索一下这个词,就可以得到大致的说明.在这里,我会对JavaScript的异步做一点额外解释. 看一下这段代码: JavaScript代码 var start = new Date(); setTimeout(function(){ var end = new Date(); console.log(&

async + promise 解决回调地狱

// 解决异步回调地狱的方案: async + promise async function writeFile() { // 打开文件 const fd = await new Promise((resolve, reject) => { // 执行 打开文件 异步操作 fs.open('c.txt', 'w', (err) => { if (!err) { // 将promise对象的状态改成 成功状态 resolve(); } else { // 将promise对象的状态改成 失败状态

Javascript async异步操作库简介

异步操作知识 在js世界中, 异步操作非常流行, nodejs就是特点基于异步非阻塞. js语言支持的异步语法包括, Promise  async await generator yield. 这些语法需要使用者了解非常清楚, 往往很困难. 下面介绍一个异步操作的超级库,可以实现很多异步操作和流程控制. async库 http://caolan.github.io/async/index.html Async is a utility module which provides straight

[Javascript] Task queue &amp; Event loop.

Javascript with Chorme v8 engine works like this : For Chorme engine, v8, it has call stack. And all the async opreations functions are stay in webapis. So everytime  you call 'setTimeout()' or http call, it will always call webapis. So, in the pictu

JavaScript执行顺序Event Loop

javascript是一门单线程语言,为了实现主线程的不阻塞,但可以用Event Loop模拟多线程操作 Event Loop中同步异步任务执行顺序: 所有异步任务都是在Event Table中注册函数,当指定的时间完成时,Event Table会将函数放入Event Queue,主线程的同步任务执行完会去Event Queue读取对应函数,进入主线程执行. js引擎monitoring process进程,当发现主进程执行栈为空,会去执行Event Queue中的函数 let data = [

深入理解Javascript单线程谈Event Loop

假如面试回答js的运行机制时,你可能说出这么一段话:"Javascript的事件分同步任务和异步任务,遇到同步任务就放在执行栈中执行,而碰到异步任务就放到任务队列之中,等到执行栈执行完毕之后再去执行任务队列之中的事件."但你能说出背后的原因吗? 1.线程与进程 进程:是系统资源分配和调度的单元.一个运行着的程序就对应了一个进程.一个进程包括了运行中的程序和程序所使用到的内存和系统资源. 线程:线程是进程下的执行者,一个进程至少会开启一个线程(主线程),也可以开启多个线程. 2.同步和异

JavaScript中 Promise的学习以及使用

今天一个哥们发过来一段js代码,没看懂,就顺便学习了一下,代码如下 Promise.resolve('zhangkai').then(value => {console.log(value)}) 经过搜索,才知道是Promise的应用,于是就做一下笔记,整理一下,以及项目中可以派上的用场. 什么是Promise对象 Promise对象是CommonJS工作组为异步编程提供的统一接口,是ECMAScript6中提供了对Promise的原生支持,Promise就是在未来发生的事情,使用Promise

JavaScript 初识Promise 对象

什么是Promise? 其实, Promise就是一个类,而且这个类已经成为ES6的标准,是 ECMAScript 6 规范的重要特性之一.这个类目前在chrome32.Opera19.Firefox29以上的版本都已经支持了,要想在所有浏览器上都用上的话就看看es6-promise吧. ES6 的 Promises 是采用了 Promises/A+ 提案的一种实现.你现在能够找到的各种第三方实现,如果是完全兼容了 Promises/A+ 的,那么就和 ES6 的 Promises 是一致的(当