dontknowhy
dontknowhy

Reputation: 2866

Node JS, Promise.all() checking null?

My code looks like below

Promise.all()....

//if previous promise is fulfilled, then it runs (if it`s not undefineded)
Promise.all()....

//if previous promise is fulfilled, then it runs (if it`s not undefineded)
Promise.all()....

The problem is that I want to check that the return value of the previous promise is not null or [undefined] rather than fulfilled. What's the way?

Upvotes: 1

Views: 1043

Answers (1)

Terry Lennox
Terry Lennox

Reputation: 30685

You could create an array of the operations to be run like [op1, op2, op3].

You could then run through this list and use Promise.allSettled() to get the result of each operation as as a list like:

[
  {status: "fulfilled", value: 10},
  {status: "rejected",  value: 20},
]

For each step, if any status is "rejected", we log and return.

// Generate a promise with 10% chance of rejection...
function generatePromise() {
    let success = Math.random() < 0.90;
    return new Promise((resolve, reject) => setTimeout(success ? resolve: reject, 100, success ? Math.floor(Math.random() * 100): new Error('Some error')));
}

function op1() {
    return [generatePromise(), generatePromise()]
}

function op2() {
    return [generatePromise(), generatePromise()]
}

function op3() {
    return [generatePromise(), generatePromise()]
}

async function runOperations(operationArr) {

    for(let idx = 0; idx < operationArr.length; idx++) {
        console.log(`Running operation ${operationArr[idx].name} (${idx + 1} of ${operationArr.length})...`)
        let result = await runOperation(operationArr[idx]);
        if (!result) {
            console.log(`Operation ${idx + 1} failed, returning...`);
            return;
        }
    }
    console.log('All operations successful!')
    return true;
}

async function runOperation(op) {
    let results = await Promise.allSettled(op());
    return !(results.find(({ status, value }) => status === 'rejected'));
}

let operationsToBeRun = [ op1, op2, op3 ];
runOperations(operationsToBeRun);
.as-console-wrapper { max-height: 100% !important; }

If Promise.allSettled is not available, you can get the same result using Promise.all, wrapping in a runOperation() method:

// Generate a promise with 10% chance of rejection...
function generatePromise() {
    let success = Math.random() < 0.90;
    return new Promise((resolve, reject) => setTimeout(success ? resolve: reject, 100, success ? Math.floor(Math.random() * 100): new Error('Some error')));
}

function op1() {
    return [generatePromise(), generatePromise()]
}

function op2() {
    return [generatePromise(), generatePromise()]
}

function op3() {
    return [generatePromise(), generatePromise()]
}

async function runOperations(operationArr) {

    for(let idx = 0; idx < operationArr.length; idx++) {
        console.log(`Running operation ${operationArr[idx].name} (${idx + 1} of ${operationArr.length})...`)
        let result = await runOperation(operationArr[idx]);
        if (!result) {
            console.log(`Operation ${idx + 1} failed, returning...`);
            return;
        }
    }
    console.log('All operations successful!')
    return true;
}

async function runOperation(op) {
    try {
        let results = await Promise.all(op());
        return true;
    } catch (err) {
        console.log(`An error occurred running ${op.name}:`, err.message);
        return false;
    }
}

let operationsToBeRun = [ op1, op2, op3 ];
runOperations(operationsToBeRun);
.as-console-wrapper { max-height: 100% !important; }

Upvotes: 1

Related Questions