如何以同步方式执行剪贴板复制,窗口打开,事件处理程序和setInterval?

时间:2018-12-29 18:56:58

标签: javascript asynchronous dom promise async-await

我正在尝试按顺序执行以下操作: 1.创建文件名 2.将该文件名复制到剪贴板 3.打开一个到特定网址的窗口 4.在新窗口中单击特定的div 5.关闭窗口 6.现在,我可以打印并粘贴粘贴的文件名,最后打印为pdf

我需要这些动作一个接一个地发生。我需要在循环内运行此逻辑(或至少执行200次)。因此,我需要执行这些步骤,然后移至我正在遍历的html表中的下一项。

let obj = {};

const copyToClipboard = (text) => {
    const tempElem = document.createElement('input');
    document.body.appendChild(tempElem);
    tempElem.setAttribute('value', text);
    tempElem.select();
    document.execCommand("copy");
    document.body.removeChild(tempElem);
};

const traverse = (i, inObj) => {
    const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
    const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
    const file = `Item: ${name}`;

    if(inObj[number] == "undefined" || inObj[poName] != status){
        inObj[number] = status;
        copyToClipboard(file);

        let url = 'mysite.com/myroute';
        let a = window.open(url);
        a.focus();
        let timer = setInterval(() => {
            a.document.getElementsByClassName('anotherid')[1].click();
            const i = a.document.getElementById('myframe');
            i.contentWindow.focus();
            i.contentWindow.print();
            a.close();
            clearInterval(timer);
            console.log('Success!');
        }, 1000);
    } else{
        console.log('Failure!');
    }
};
for(let i = 0; i < tableSize; i++{
    traverse(i, obj);
}

我的某些代码将在其他代码之前执行。例如,所有窗口将立即打开,然后执行其余操作。我需要此代码在下一次索引迭代之前完全在循环内执行。

1 个答案:

答案 0 :(得分:2)

我在您的代码中看到的唯一异步内容是traverse的完成。因此,只需定义traverse即可返回承诺。给定traverse中的代码,如果您明确进行此操作,这可能是最简单的:

const traverse = (i, inObj) => {
    return new Promise((resolve, reject) => {  // <===========================
        const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
        const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
        const file = `Item: ${name}`;

        if(inObj[number] == "undefined" || inObj[poName] != status){
            inObj[number] = status;
            copyToClipboard(file);

            let url = 'mysite.com/myroute';
            let a = window.open(url);
            a.focus();
            let timer = setInterval(() => {
                a.document.getElementsByClassName('anotherid')[1].click();
                const i = a.document.getElementById('myframe');
                i.contentWindow.focus();
                i.contentWindow.print();
                a.close();
                clearInterval(timer);
                console.log('Success!');
                resolve();                     // <===========================
            }, 1000);
            // *** Probably want to do a timeout here in case the window never loads
        } else{
            console.log('Failure!');
            reject();                          // <===========================
        }
    });
};

然后:

  1. 如果可以使用async语法,请在await返回的promise上使用traverse编写循环。示例:

    // In an `async` function
    try {
        for (let i = 0; i < tableSize; ++i) {
            await traverse(i, obj);
        }
        // Done
    } catch (error) {
        // An error occurred
    }
    
  2. 如果没有,请通过then返回的prom调用traverse将您的操作链接在一起:

    let promise = Promise.resolve();
    for (let i = 0; i < tableSize; ++i) {
        promise = promise.then(() => traverse(i, obj));
    }
    promise
    .then(() => {
        // Done
    })
    .catch(error => {
        // An error occurred
    };
    

更新`tra