简体   繁体   中英

node Promise chain resolution not waiting for .then

I have this particular Promise chain with the promise and 1 then. I want the first Promise to run and populate an object with keyed values. This works fine.

I then want a .then function to execute which will concat some values to the original object. Again this is working fine.

My problem is the resolve is occurring before the .then completes which is not what I want. I understood .then would execute and finally return result before the resolve settles. If I simplify the code to just simply concat the value it works. I believe my problem is the first operation in the .then is itself an async object. I am not sure how to make the .then wait for binance.prevDay to complete before returning result.

The console.log output looks like this:

Resolving
Resolved
฿0.00153400
entered
Exit฿0.00153400
$14

All values are what I want, but I want the Resolved to be at the end.

promise2 = new Promise((resolve, reject) => {
        binance.prevDay(coin + `BTC`, (error, prevDay, symbol) => {
            for (var obj in prevDay) {
                if (obj.includes("priceChangePercent")) {
                    _add24h["24h Percent"] = new Number(parseFloat(prevDay[obj]).toFixed(2)) + `%`;
                } else
                if (obj.includes("priceChange")) {
                    _add24h["24h Change"] = `\u0E3F` + prevDay[obj]; // + `\n\$` + parseFloat(prevDay[obj]*_btcusdt).toFixed(2);
                } else
                if (obj.includes("highPrice")) {
                    _add24h["24h High"] = `\u0E3F` + prevDay[obj];
                } else
                if (obj.includes("lowPrice")) {
                    _add24h["24h Low"] = `\u0E3F` + prevDay[obj];
                }
            }
            console.log("Resolving")
            resolve(_add24h);
            console.log("Resolved")
        })
    })
    .then(function (result) {
        binance.prevDay(coin + `USDT`, (error, prevDay, symbol) => {
            for (var obj in prevDay) {
                //console.log(prevDay[obj]);
                if (obj.includes("priceChangePercent")) {
                    _add24h["24h Percent"] = prevDay[obj];
                } else
                if (obj.includes("priceChange")) {
                    console.log("entered")
                    _add24h["24h Change"] = _add24h["24h Change"] + "\n$" + new Number(parseFloat(prevDay[obj]).toFixed(2));
                    console.log("Exit" + _add24h["24h Change"])
                }
            }
        })
        console.log(_add24h["24h Change"])
        return result;
    })

From what I understand, that is the expected order of execution.

Calling resolve() inside your first promise does not necessarily execute the then handler immediately (ie, calling resolve does not add the then handler to the call stack).. It will be queued for execution and the call to resolve returns, and the console.log("Resolved") in the promise handler. The then method is executed later on the 'next tick' assuming nothing else has been queued up.

However, this is just my superficial understanding and it may depend on the implementation of Promises used.

Calling .resolve() or .reject() is an asynchronous action, and is just a signal to the associated handler that the promise has been fulfilled or rejected. It doesn't necessarily mean that the next lines will be executed only after the then part has completed execution.

Please read the official javascript documentation on promises to have a better understanding: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

In order to have "Resolved" at the end, you should put it at the end of your then() chain.

The important point here is: resolve resolves a promise and not a promise chain.
You have two promises in your code:
The one you create with new Promise and the one you create with .then .
As expected, the call to resolve resolves the first promise. This is the prerequisite for the second promise to run. If you wouldn't call resolve on the first promise, the .then promise would never run.

If you want code to run after your .then , append that code with another .then .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM