Javascript 使用fs.writeFileSync时避免争用条件

Javascript 使用fs.writeFileSync时避免争用条件,javascript,node.js,Javascript,Node.js,我正在使用bluebird、request promise和writeFileSync下载png并将其写入文件,我的代码是:` function downloadPng(url) { return new Promise(function (resolve, reject) { return request.get({ url : url, headers : header, encoding: 'b

我正在使用bluebird、request promise和writeFileSync下载png并将其写入文件,我的代码是:`

function downloadPng(url) {
    return new Promise(function (resolve, reject) {
        return request.get({
            url : url,
            headers : header,
            encoding: 'binary',
        }).then((res) => {
            fs.writeFileSync('fileName', res, 'binary')
            return foo('fileName')//my function using fileName
        }).then((resultFromFoo) => {
            resolve(resultFromFoo)        
        }).catch((error) => {
            reject(error)
        })

我认为使用writeFileSync可以确保只有在writeFileSync成功后才会执行foo?但是我仍然得到一个竞争条件,在创建文件之前调用了我的foo,我如何正确地做到这一点?

问题更可能出现在其他地方,显示的代码应该可以工作,只要不同时调用
downloadPng

除此之外,在此处创建新承诺没有意义,因为
request.get
已经返回了一个承诺,而不是
Sync
,您应该使用指定版本的write命令:

const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs'))

function downloadPng(url) {
  return request.get({
      url: url,
      headers: header,
      encoding: 'binary',
    }).then(res => {
      return fs.writeFileAsync('fileName', res, 'binary')
    })
    .then(() => {
      return foo('fileName') //my function using fileName
    })
})
如果您可以使用
wait
async
,您可以这样编写:

const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs'))

async function downloadPng(url) {
  var res = await request.get({
    url: url,
    headers: header,
    encoding: 'binary',
  });

  await fs.writeFileAsync('fileName', res, 'binary')

  return foo('fileName')
})

为什么你要创造一个承诺,却从不要求解决或拒绝?这很奇怪。此代码应该可以工作,并且应该在调用
foo()
之前完成文件的编写。更可能的情况是问题出在其他地方,只要不同时调用
downloadPng
,显示的代码应该可以工作。此外,在这里创建一个新的承诺是没有意义的,因为
request.get
已经返回了一个承诺。