解决调用自己的函数的Promise

时间:2018-02-01 18:43:02

标签: javascript promise es6-promise

如果我调用此功能,它似乎无法正常工作。它正在做的只是等待全局变量" window.AppApi"在做事之前进行初始化

我觉得也许是因为我在超时时再次调用该功能?有什么我不想做的工作吗?如果它不可能会是一个好的选择......

initializeApp()
  .then(( result ) => {
    console.log( 'it worked!' );  // does not go here
  });


export const initializeApp = () => {
  return new Promise(( resolve, reject ) => {
    // wait for App API to be initialized
    if ( window.AppApi ) {
      console.log( 'App initialized.' );
      resolve( true );
    }
    else {
      console.log( 'waiting for App to initialize...' );
      setTimeout( () => initializeApp(), 250 );
    }
  });
};

5 个答案:

答案 0 :(得分:5)

从技术上讲,即使没有使用旧的优秀Object.defineProperty setter进行脏超时,你也可以做到这一点:

const initializeApp = () => {
  return new Promise((resolve, reject) => {
    if (window.AppApi) {
      resolve(true);
      return;
    }

    Object.defineProperty(window, 'AppApi', {
      set (value) {
        console.log('App initialized.');
        resolve(true);
        return value
      }
    })
  });
};

initializeApp()
  .then((result) => {
    console.log('it worked!'); // does not go here
  });

setTimeout(() => {
  window.AppApi = { test: 123 }
}, 2000)

答案 1 :(得分:4)

问题在于setTimeout( () => initializeApp(), 250 )将创建一个未在任何地方使用的新Promise,并且创建的第一个Promise - 与您的第一个代码块唯一相关的 - 只有在{{ {1}}在第一次调用window.AppApi之前设置。

你必须写这样的东西:

initializeApp

答案 2 :(得分:3)

您可以将其定义为解析承诺的getter,而不是轮询此值:



const initializeApp = () => new Promise(resolve => {
  const { AppApi } = window;
  if (AppApi) return resolve(AppApi);
  Object.defineProperty(window, 'AppApi', {
    get () { return AppApi; },
    set (value) {
      console.log('App initialized.');
      Object.defineProperty(window, 'AppApi', {
        value,
        enumerable: true,
        configurable: true,
        writable: true
      });
      resolve(value);
    },
    enumerable: true,
    configurable: true
  });
});

initializeApp().then(AppApi => {
  console.log(AppApi);
});

setTimeout(() => window.AppApi = { test: 123 }, 1000);




这使用Object.defineProperty()创建一个属性访问器,当API被标记为就绪时立即解析承诺。这还有一个额外的好处,即使用AppApi的值进行解析,因此,如果它是一个名称空间,您可以将它作为.then()的回调函数的第一个参数。

答案 3 :(得分:1)

我认为问题在于,pip install git+https://github.com/Theano/Theano.git 函数每次调用时都会创建一个新的承诺。因此,当它以递归方式调用时,原始承诺将丢失并永远无法解决。相反,将递归部分放入其自己的子函数中,并以递归方式调用:

initializeApp

答案 4 :(得分:0)

由于window.AppApi是将来可用的值,您可能会想到一个代表该对象的对象.....

承诺。

如果window.AppApi设置为AppApi的承诺,那么当您想要使用它时,您可以这样做:

window.AppApi.then(...

但为了做到这一点,你不应该展示initializeApp,而应该展示设置AppApi的代码以及你如何做到这一点。因为似乎initializeApp解决了一个问题(在某些答案中非常优雅),这首先不应该存在。