搞砸了吗?

时间:2018-10-25 12:07:14

标签: javascript promise async-await

最近几天,这个问题一直困扰着我。我还不是一名Javascript专家,可能解决方案很明显,但我看不到。

我基本上想做的是:

  1. 以并行方式下载项目,每个请求都是针对给定的 具有不同属性的项目类型(类型1,类型2)。
  2. 下载后,执行回调函数以对数据进行后处理 (这是具有不同参数和测试的相同功能 物品类型以进行不同的处理)
  3. 保存项目

如果我下载一种项目类型,则一切正常。但是,如果我下载了2种类型,那么在第一次回调执行中的处理循环中的某个时间点,正是当第二次针对第二种类型执行第二次回调时,对类型的测试将表明它是第二种类型,而项属于第一类型...

以下是代码的摘录:

downloadType1();
downloadType2();

// 2nd argument of download() is the callback function
// 3rd argument is the callback function parameters
function downloadType1() {
    // Some stuff here
    let callbackParameters = ['type1', 'directory1'];
    download('url', headacheCallback, callbackParameters);
}

function downloadType2() {
    // Some the stuff here
    let callbackParameters = ['type2', 'directory2'];
    download('url', headacheCallback, callbackParameters);
}

async function download(url, callbackBeforeSave, callbackParameters) {
    // Some stuff here
    let response;
    try {
        response = await rp(url);
    } catch (e) {
        console.log("Error downloading data");
    }

    // Call callbacks before saving the data
    if(callbackBeforeSave) {
        let updatedResponse;

        if (callbackParameters) {
            updatedResponse = await callbackBeforeSave(response, ...callbackParameters);
        } else {
            updatedResponse = await callbackBeforeSave(response);
        }

        response = updatedResponse;
    }
    
    // Some stuff here with the post-processed data
}

async function headacheCallback(data, type, directory) {
    for (item of data) {
        // Some stuff here, include async/await calls (mostly to download and save files)
        
        console.log(type, item.propertyToUpdate, item.child.propertyToUpdate);
        // This is were my issue is.
        // The test will success although I'm still the 'type1' loop. I know because the console.log above shows the item is indeed of type 'type1'
        if (type === 'type2') {
            item.child.propertyToUpdate = newUrl; // Will eventually fail because 'type1' items don't have a .child.propertyToUpdate property 
        } else {
            item.propertyToUpdate = newUrl;
        }
    }
}

在某个时候,console.log的输出将是: type2 <valueOfTheProperty> undefined应该是type2 undefined <valueOfTheProperty> ...

快速思考:在回调的第一个版本中,我将arguments全局变量与function.apply(...)结合使用。这之所以很糟糕,恰恰是因为arguments是全局的,因此在第二次调用之后被更改了。

但是现在我看不到代码中的任何全局信息可以解释type为何改变的原因。

任何帮助将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:1)

  

我在代码中看不到任何可以解释类型变化的全局信息。

变化的不是type。您的问题是involuntary globalitem

for (item of data) {
//   ^^^^

做个

for (const item of data) {
//   ^^^^

并始终启用严格模式!

答案 1 :(得分:0)

这是Promise.all的工作

const p1 = new Promise((res, rej) => res());
Promise.all([p1, p2]).then((results) => results.map(yourFunction));

Promise.all将返回已解决的数组,否则可能会拒绝。但是,如果您使用仅能解决的新Promise设置p1,p2,pn,则不必拒绝。然后,您的功能图就可以处理分支并为正确的响应类型做正确的事情。有道理吗?