javascript 无法使用Promise为重承诺添加超时,race [duplicate]

nkhmeac6  于 2023-01-04  发布在  Java
关注(0)|答案(1)|浏览(118)
    • 此问题在此处已有答案**:

Correct way to write a non-blocking function in Node.js(2个答案)
7小时前关闭。
我正在使用React Native和Expo进行移动应用程序开发。我承诺调用GeoFirestore按距离顺序查询来自firebase firestore的数据,但由于GeoFirestore查询未完成,我的应用程序有时会崩溃。
因此,我需要在重承诺中添加一个超时,我尝试使用Promise. race,其中包含两个承诺,一个承诺调用GeoFirestore API,另一个承诺使用SetTimeout在给定时间后拒绝,如以下代码所示(使用无限循环代替实际的GeoFirestore调用,以便其可执行)。
但是,我发现setTimeout不会拒绝,即使时间超过了给定的时间。
我们怎样才能在沉重的承诺上加上一个暂停呢?
我猜javascript运行在单线程上,繁重的操作需要一个线程,但计时器任务无法运行...

const makeTimeoutPromise = (timeMs) => new Promise(function(resolve, reject) {
  setTimeout(() => reject(`timeout`), timeMs);
});

const heavyOperationPromise = () => new Promise(function(resolve, reject) {
  while (true) { } // a very heayy operation. 
  resolve();
});

const test = async () => {
  try {
    console.log('test started');
    const result = await Promise.race([makeTimeoutPromise(100), heavyOperationPromise()]);
    console.log(`done result=${result}`);
  } catch (e) {
    console.log(`catch e=${e}`);
  }
}

test();
brccelvz

brccelvz1#

如果繁重的操作不是async,它就不会给予setTimeout回调从事件循环执行的机会,如果给它一个喘息的空间,它就会工作。

function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}

const makeTimeoutPromise = (timeMs) => new Promise(function(resolve, reject) {
  setTimeout(() => reject(`timeout`), timeMs);
});

const heavyOperationPromise = () => new Promise(async function(resolve, reject) {
  while (true) {
    await sleep(1);
  } // a very heayy operation. 
  resolve();
});

const test = async () => {
  try {
    console.log('test started');
    const result = await Promise.race([makeTimeoutPromise(100), heavyOperationPromise()]);
    console.log(`done result=${result}`);
  } catch (e) {
    console.log(`catch e=${e}`);
  }
}

test();

相关问题