承诺不要彼此等待

时间:2016-11-01 18:17:47

标签: javascript promise es6-promise

因此,我对承诺的理解使我相信我的其他承诺会在我当时的链中一个接一个地运行,但我在这里做错了。

我目前使用的代码如下

const mainPromise = () => Promise.resolve(
    console.log('spinner spinning...')
    ...spinner code.... //this is omitted code
);

const getData = () => Promise.resolve(
    someObj.getProducts('data.json')
);

const updateProduct = () => Promise.resolve(
    setTimeout(()=>{
        someObj.updateProductHTML()
    }, 0)
);

const updateDom = () => {
    setTimeout(()=>{
        someObj.updateDOM()
    }, 0)
};

和我的承诺链

mainPromise()
    .then(getData)
    .then(updateProduct)
    .then(updateDom)
;

它们似乎最初按顺序运行,但我在getProducts中的Ajax调用也有一个for循环工作程序来构建我的对象数组,并且在我的所有.thens运行后完成。

我试图在updateProduct和updateDOM运行之前至少完成数据调用和工作完成

---更新---

好的,根据评论中的建议和Samanime的答案设置修改后的承诺

 const mainPromise = () => Promise.resolve(
    console.log('spinner spinning...')
);

const getData = () => new Promise( resolve => {
    console.log('getData');
        someObj.getProducts('data.json');
        resolve();
    }
);

const updateProduct = () => new Promise( resolve =>{
   console.log('updateProduct');
   someObj.updateProductHTML();
   resolve();
});

//execute promise chain

mainPromise()
    .then(getData)
    .then(updateProduct)
    .then(page.updateDOM)
;

我更新了承诺,没有立即解决,并且在我调用我的函数后尝试调用resolve(虽然我对在这些函数之前或之后调用resolve是否感到不安)。

不幸的是,我仍然有同样的行为。我已将控制台日志添加到我的功能以及我的承诺中,并且我已将此列表恢复

   log.spinner spinning
   log.getData
   log.updateProduct
   log.A log from the function updateProduct calls
   log.48 product objects created (for loop worker in my getProducts   function)
   log.Data retrieved and assigned
   the last two logs would ideally be called after getData

所提供的电话或功能之外的所有电话或功能都不是返回承诺,我正在处理遗留代码,而且我正在远离setTimeout技巧以及我的结果并非一致

- 更新2 -

我遇到的问题被称为分叉/分裂。我只需要弄清楚链接专门解决我的问题。

- 最终 -

这就是我最终解决的问题

 // execute promise chain

mainPromise()
    .then(getData);

//the timeout is a little hack to ensure the sequence is kept
mainPromise()
    .then(() => {
        setTimeout(() => {
            myObj.updateProductHTML();
            myObj.updateDOM();
        }, 0);

    });

显然.then(foo).then(bar)只是同时运行foo和bar

似乎工作正常,但我觉得有些事情还不合适。

1 个答案:

答案 0 :(得分:3)

我相信它是因为Promise.resolve()没有做到你认为的那样。

Promise.resolve()创建一个新的Promise,并使用其给出的立即解析它。 setTimeout之类的东西会立即返回他们的id(整数),所以他们没有做你想做的事。您的getProducts()可能是异步调用,因此它可能会返回null或其他内容(如果它返回Promise或同步返回值,那么&#39} ;很好)。

你最好写一个正常的Promise并在适当的时候调用resolve()

const mainPromise = () => Promise.resolve(
    console.log('spinner spinning...')
    ...spinner code....
);

// Assuming it's already returning a Promise or synchronous response. If it isn't, then deal with it like the setTimeout ones below.
const getData = () => someObj.getProducts('data.json')

const updateProduct = () => new Promise(resolve => {
    setTimeout(()=>{
        someObj.updateProductHTML();
        resolve();
    }, 0)
});

// You don't NEED to in your example since it's at the end of the chain, but you probably want to wrap this too in case you add to the chain.
const updateDom = () => new Promise(resolve => {
    setTimeout(()=>{
        someObj.updateDOM();
        resolve();
    }, 0)
});