Javascript 如何等待幻影';完成写作

Javascript 如何等待幻影';完成写作,javascript,asynchronous,file-io,phantomjs,Javascript,Asynchronous,File Io,Phantomjs,我正在开发一个PhantomJS脚本来下载网站的所有资源,并在执行bash脚本时对它们进行测试 为此,当我使用fs.write()保存文件,然后使用execFile()执行bash脚本时,我编写了page.onResourceReceived方法 (这不是全部onResourceReceived代码) 若我为execFile配置回调,它会抛出一个并没有这样的文件或目录错误,但随后,我会检查目录和文件是否存在 我认为这可能是一个同步问题 fs.write是异步方法吗 是否有其他方法可以同步执行fs

我正在开发一个PhantomJS脚本来下载网站的所有资源,并在执行bash脚本时对它们进行测试

为此,当我使用fs.write()保存文件,然后使用execFile()执行bash脚本时,我编写了page.onResourceReceived方法

(这不是全部onResourceReceived代码)

若我为execFile配置回调,它会抛出一个并没有这样的文件或目录错误,但随后,我会检查目录和文件是否存在

我认为这可能是一个同步问题

  • fs.write是异步方法吗

  • 是否有其他方法可以同步执行fs.write和execFile方法

  • 更新

    我也试过:

    function waitForFile(filePath, attempts) {
        var fileExists = false;
        var i = 0;
        while (!fileExists && i < attempts) {
            wait(50);
            fileExists = fs.exists(filePath) && fs.isFile(filePath) && fs.size(filePath) > 0;
            i++;
        }
    }
    
    page.onResourceReceived = function(resource) {
        if (resource.stage == 'end') {
            fileName = getFileNameFromURL(resource.url);
            fs.write('files/' + fileName, resource.body, 'wb');
            waitForFile('files/' + fileName, 5);
            execFile('sh', [SH_PATH, 'files/' + fileName], null, null);
        }
    }
    
    函数waitForFile(文件路径,尝试次数){
    var fileExists=false;
    var i=0;
    而(!fileExists&&i<尝试次数){
    等待(50);
    fileExists=fs.exists(filePath)&&fs.isFile(filePath)&&fs.size(filePath)>0;
    i++;
    }
    }
    page.onResourceReceived=函数(资源){
    如果(resource.stage=='end'){
    fileName=getFileNameFromURL(resource.url);
    write('files/'+文件名,resource.body,'wb');
    waitForFile('files/'+文件名,5);
    execFile('sh',[sh_路径,'files/'+文件名],null,null);
    }
    }
    

    其中wait()是一个函数,它使线程在X毫秒内保持忙碌。

    fs.在PhantomJS中编写
    方法以进行回调

    只需添加一点超时,让操作系统有时间完成对磁盘的写入

    page.onResourceReceived = function(resource) {
        if (resource.stage == 'end') {
            fileName = getFileNameFromURL(resource.url);
            fs.write('files/' + fileName, resource.body, 'wb');
    
            setTimeout(function(){
                execFile('sh', [SH_PATH, 'files/' + fileName], null, null);
            }, 500);
    
        }
    }
    

    解决此问题的一种方法是将
    fs.write()
    调用封装在一个函数中,该函数返回一个
    Promise
    对象,并在解析返回的
    Promise
    后继续执行
    exeFile()
    调用。有几个JS库可以帮助您明确地做到这一点。我个人使用

    另一种方法是使用。在IMO中,这有助于在多个场景(可能包括此场景)中实现更干净、更可读和可维护的代码/流


    本文简要介绍了
    Promise
    方法,并向初学者充分解释了Async.js要点。

    感谢您的回答。我尝试过,但即使有延迟,在执行bash脚本时仍有一些资源失败。我将以更大的延迟重试,但我认为应该有更好的解决方案。超时不是在异步调用中实现同步/排序的有效方法,是一种不好的做法。同意,这种方法在可读性和以后的扩展性方面肯定更好。请使用您选择的库提供OP情况的代码示例。感谢您的回答和链接。我对承诺一无所知。但是,执行回调的承诺会检测到什么?我的意思是,fs.write()方法完成了,尽管文件实际上并不存在。是否有可能在完成fs.write()方法时调用回调,从而导致相同的行为?
    page.onResourceReceived = function(resource) {
        if (resource.stage == 'end') {
            fileName = getFileNameFromURL(resource.url);
            fs.write('files/' + fileName, resource.body, 'wb');
    
            setTimeout(function(){
                execFile('sh', [SH_PATH, 'files/' + fileName], null, null);
            }, 500);
    
        }
    }