Как выполнить копирование буфера обмена, открытие окна, обработчик событий и setInterval в синхронном режиме? - PullRequest
0 голосов
/ 29 декабря 2018

Я пытаюсь выполнить следующие действия по порядку: 1. Создать имя файла 2. Скопировать это имя файла в буфер обмена 3. Открыть окно с определенным URL-адресом 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 голосов
/ 29 декабря 2018

Единственная асинхронная вещь, которую я вижу в вашем коде - это завершение 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 в обещании, возвращенном 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 в обещании, возвращенном 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

...