question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Promises acting synchronously

See original GitHub issue

Greetings!

When it comes to promises, I hail from the land of AngularJS, which includes a few nice wrappers. I’ve only had to deal with pure promises a few times, so this issue is most likely me not understanding how to set this up (and there is a lack of basic examples in the README, instead directing readers to the spec)

This is the current code I have:

from promise import Promise
import urllib.request

url = 'https://jsonplaceholder.typicode.com/photos'

def success(data):
    print("promise success!")
    # print(data)

def reject(data):
    print("rejected!")
    print(data)

def getData(url):
    def func(resolve, reject):
        
        req = urllib.request.urlopen(url)
        if req.getcode() == 200:
            resolve(req.read())
        else:
            reject(Exception(req.getcode()))

    return Promise(func)

print("getting resource")
p = getData(url)
p.then(success, reject)
print("Waiting on promise")

This seems to work synchronously: once getData() is called, it returns a promise, but it also blocks execution. This is what the output looks like:

getting resource
promise success!
Waiting on promise

The order I was expecting:

getting resource
Waiting on promise
promise success!

I’ve also tested this with a simple time.sleep(5) and resolving immediately after that. Again, once getData() is run, it simply sleeps for 5 seconds without hitting the “Waiting” print, then continues onword.

Sorry if this is a bit of an obtuse question, I acknowledge I’m probably not working with it correctly, but I can’t seem to figure it out.

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:3
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
pkopaccommented, Feb 10, 2018

Hi! I’ve just tried a variant of your code example with time measuring and multiple promises locally and… it really doesn’t work (python 3.6):

Bug 1: Promise(func) executes immediately and blocks main thread, whatever the scheduler.

Bug 2: Promise.promisify(func) returns a function, not a promise.

Executing promises
0
Time elapsed (hh:mm:ss.ms) 0:00:02.121857
1
Time elapsed (hh:mm:ss.ms) 0:00:06.121378
2
Time elapsed (hh:mm:ss.ms) 0:00:11.926724
[<Promise at 0x7f00fa7180b8 pending>, <Promise at 0x7f00fa701a58 pending>, <Promise at 0x7f00fa7289e8 pending>]
Waiting on all promises
promise success!
promise success!
promise success!
Time elapsed (hh:mm:ss.ms) 0:00:11.928643

With ThreadScheduler:

Executing promises
0
promise success!
Time elapsed (hh:mm:ss.ms) 0:00:01.692070
1
promise success!
Time elapsed (hh:mm:ss.ms) 0:00:03.782801
2
promise success!
Time elapsed (hh:mm:ss.ms) 0:00:05.826248
[<Promise at 0x7fd12df93a90 fulfilled with None>, <Promise at 0x7fd12de42cc0 fulfilled with None>, <Promise at 0x7fd12de5a320 fulfilled with None>]
Waiting on all promises
Time elapsed (hh:mm:ss.ms) 0:00:05.827753

My full code:

from promise import Promise, set_default_scheduler, get_default_scheduler
from promise.schedulers.asyncio import AsyncioScheduler
from promise.schedulers.gevent import GeventScheduler
from promise.schedulers.thread import ThreadScheduler
from datetime import datetime
import urllib.request

# set_default_scheduler(AsyncioScheduler())
set_default_scheduler(ThreadScheduler())
# set_default_scheduler(GeventScheduler())

url = 'https://jsonplaceholder.typicode.com/photos'
def getData(url):
    def func(resolve, reject):
        req = urllib.request.urlopen(url)
        if req.getcode() == 200:
            resolve(req.read())
        else:
            reject(Exception(req.getcode()))

    return Promise(func)

start_time = datetime.now()

def success(data):
    print("promise success!")
    # print(data)

def reject(data):
    print("rejected!")
    print(data)

def print_elapsed_time():
    time_elapsed = datetime.now() - start_time
    print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))

print("Executing promises")
l = []
for x in range(0, 3):
    print(x)
    l.append(getData(url).then(success, reject))
    print_elapsed_time()

print(l)
print("Waiting on all promises")
Promise.all(l).get()
print_elapsed_time()

I was able to get it work as async promises with a really ugly syntax:

def getDataHack(url):
    def func(value):
        req = urllib.request.urlopen(url)
        if req.getcode() == 200:
            Promise.resolve(req.read())
        else:
            Promise.reject(Exception(req.getcode()))

    return Promise.resolve("foo").then(func, None)
Executing promises
0
Time elapsed (hh:mm:ss.ms) 0:00:00.001408
1
Time elapsed (hh:mm:ss.ms) 0:00:00.001448
2
Time elapsed (hh:mm:ss.ms) 0:00:00.001474
[<Promise at 0x7f8e75321eb8 pending>, <Promise at 0x7f8e75321fd0 pending>, <Promise at 0x7f8e7533a0f0 pending>]
Waiting on all promises
promise success!
promise success!
promise success!
Time elapsed (hh:mm:ss.ms) 0:00:05.912553
2reactions
pollarocommented, Dec 16, 2019

I’m having trouble with my DataLoader queueing things. It seems to load the data immediately when I call load() instead of waiting.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Javascript promises not acting synchronously - Stack Overflow
I am attempting to use JavaScript promises so that the rest of my code waits for my asynchronous 'chrome.storage.local.get' call. However, it ...
Read more >
Making promises in a synchronous manner - Tivix
log(result); }); First we define the 'asyncTask' function. When called, it returns a promise which will be resolved with a random delay.
Read more >
Convert Asynchronous calls to Synchronous in JavaScript
Promises. A Promise constructor is used to evaluate asynchronous code in a synchronous way. A Promise is a proxy for a value. Syntax:....
Read more >
Learn JavaScript Promises by Building a Custom ...
A promise acts as a synchronous value - it can be passed as an argument or returned by functions as usual. However, to...
Read more >
Futures and promises - Wikipedia
In computer science, future, promise, delay, and deferred refer to constructs used for synchronizing program execution in some concurrent programming ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found